<JVM上篇:内存与垃圾回收篇>01-JVM与Java体系结构(一)

简介: <JVM上篇:内存与垃圾回收篇>01-JVM与Java体系结构

1.JVM 与 Java 体系结构

1.1. 前言


作为 Java 工程师的你曾被伤害过吗?你是否也遇到过这些问题?


运行着的线上系统突然卡死,系统无法访问,甚至直接 OOM

想解决线上 JVM GC 问题,但却无从下手

新项目上线,对各种 JVM 参数设置一脸茫然,直接默认吧然后就 JJ 了

每次面试之前都要重新背一遍 JVM 的一些原理概念性的东西,然而面试官却经常问你在实际项目中如何调优 JVM 参数,如何解决 GC、OOM 等问题,一脸懵逼

a0467ead4c3e93dad3959bda9ba9dddb.png大部分 Java 开发人员,除会在项目中使用到与 Java 平台相关的各种高精尖技术,对于 Java 技术的核心 Java 虚拟机了解甚少


开发人员如何看待上层框架


一些有一定工作经验的开发人员,打心眼儿里觉得 SSM、微服务等上层技术才是重点,基础技术并不重要,这其实是一种本末倒置的“病态”。


如果我们把核心类库的 API 比做数学公式的话,那么 Java 虚拟机的知识就好比公式的推导过程。


98b859605e096d506103844cd77ebdbe.png


计算机系统体系对我们来说越来越远,在不了解底层实现方式的前提下,通过高级语言很容易编写程序代码。但事实上计算机并不认识高级语言


我们为什么要学习 JVM?


面试的需要(BATJ、TMD,PKQ 等面试都爱问)

中高级程序员必备技能

项目管理、调优的需求

追求极客的精神

比如:垃圾回收算法、JIT、底层原理

Java vs C++


84700e97a94843d0872353607286c115.jpg


垃圾收集机制为我们打理了很多繁琐的工作,大大提高了开发的效率,但是,垃圾收集也不是万能的,懂得 JVM 内部的内存结构、工作机制,是设计高扩展性应用和诊断运行时问题的基础,也是 Java 工程师进阶的必备能力。


1.2. 面向人群及参考书目


f4be571105a1e55e49dbbb75174a4716.png


9b515c6a3dafbd98a2525f3233e7b177.png

ba6e0330ccd8bc588332925078dc18d1.png

105e75381a39dab3cbde47955ff1a4f5.png


1.3. Java 及 JVM 简介

TIOBE 语言热度排行榜:index | TIOBE - The Software Quality Company


Programming Language 2021 2016 2011 2006 2001 1996 1991 1986
C 1 2 2 2 1 1 1 1
Java 2 1 1 1 3 26 - -
Python 3 5 6 8 27 19 - -
C++ 4 3 3 3 2 2 2 8
C# 5 4 5 7 13 - - -
Visual Basic 6 13 - - - - - -
JavaScript 7 8 10 9 10 32 - -
PHP 8 6 4 4 11 - - -
SQL 9 - - - - - - -
R 10 17 31 - - - - -
Lisp 34 27 13 14 17 7 4 2
Ada 36 28 17 16 20 8 5 3
(Visual) Basic - - 7 6 4 3 3 5


世界上没有最好的编程语言,只有最适用于具体应用场景的编程语言


JVM:跨语言的平台


Java 是目前应用最为广泛的软件开发平台之一。随着 Java 以及 Java 社区的不断壮大 Java 也早已不再是简简单单的一门计算机语言了,它更是一个平台、一种文化、一个社区。


作为一个平台,Java 虚拟机扮演着举足轻重的作用

Groovy、Scala、JRuby、Kotlin 等都是 Java 平台的一部分

作为灯种文化,Java 几乎成为了“开源”的代名词。

第三方开源软件和框架。如 Tomcat、Struts,MyBatis,Spring 等。

就连 JDK 和 JVM 自身也有不少开源的实现,如 openJDK、Harmony。

作为一个社区,Java 拥有全世界最多的技术拥护者和开源社区支持,有数不清的论坛和资料。从桌面应用软件、嵌入式开发到企业级应用、后台服务器、中间件,都可以看到 Java 的身影。其应用形式之复杂、参与人数之众多也令人咋舌。


caf11c8d55bf4368bb37a16e0905f520.jpg


每个语言都需要转换成字节码文件,最后转换的字节码文件都能通过 Java 虚拟机进行运行和处理


1400061bd92f4760916939ad15634c3a.jpg


随着 Java7 的正式发布,Java 虚拟机的设计者们通过 JSR-292 规范基本实现在Java 虚拟机平台上运行非 Java 语言编写的程序。


Java 虚拟机根本不关心运行在其内部的程序到底是使用何种编程语言编写的,它只关心“字节码”文件。也就是说 Java 虚拟机拥有语言无关性,并不会单纯地与 Java 语言“终身绑定”,只要其他编程语言的编译结果满足并包含 Java 虚拟机的内部指令集、符号表以及其他的辅助信息,它就是一个有效的字节码文件,就能够被虚拟机所识别并装载运行。


Java不是最强大的语言,但是JVM是最强大的虚拟机


字节码


我们平时说的 java 字节码,指的是用 java 语言编译成的字节码。准确的说任何能在 jvm 平台上执行的字节码格式都是一样的。所以应该统称为:jvm 字节码。

不同的编译器,可以编译出相同的字节码文件,字节码文件也可以在不同的 JVM 上运行。

Java 虚拟机与 Java 语言并没有必然的联系,它只与特定的二进制文件格式—Class 文件格式所关联,Class 文件中包含了 Java 虚拟机指令集(或者称为字节码、Bytecodes)和符号表,还有一些其他辅助信息。

多语言混合编程


Java 平台上的多语言混合编程正成为主流,通过特定领域的语言去解决特定领域的问题是当前软件开发应对日趋复杂的项目需求的一个方向。

试想一下,在一个项目之中,并行处理用 Clojure 语言编写,展示层使用 JRuby/Rails,中间层则是 Java,每个应用层都将使用不同的编程语言来完成,而且,接口对每一层的开发者都是透明的,各种语言之间的交互不存在任何困难,就像使用自己语言的原生 API 一样方便,因为它们最终都运行在一个虚拟机之上。

对这些运行于 Java 虚拟机之上、Java 之外的语言,来自系统级的、底层的支持正在迅速增强,以 JSR-292 为核心的一系列项目和功能改进(如 Da Vinci Machine 项目、Nashorn 引擎、InvokeDynamic 指令、java.lang.invoke 包等),推动 Java 虚拟机从“Java 语言的虚拟机”向 “多语言虚拟机”的方向发展。

如何真正搞懂 JVM?


Java 虚拟机非常复杂,要想真正理解它的工作原理,最好的方式就是自己动手编写一个!


自己动手写一个 Java 虚拟机,难吗?


天下事有难易乎?


为之,则难者亦易矣;不为,则易者亦难矣


fef253ecacda2118f4d2a951c7059a35.png


1.4. Java 发展的重大事件


1990 年,在 Sun 计算机公司中,由 Patrick Naughton、MikeSheridan 及 James Gosling 领导的小组 Green Team,开发出的新的程序语言,命名为 oak,后期命名为 Java

1995 年,Sun 正式发布 Java 和 HotJava 产品,Java 首次公开亮相。

1996 年 1 月 23 日,Sun Microsystems 发布了 JDK 1.0。

1998 年,JDK1.2 版本发布。同时,sun 发布了 JSP/Servlet、EJB 规范,以及将 Java 分成了 J2EE、J2SE 和 J2ME。这表明了 Java 开始向企业、桌面应用和移动设备应用 3 大领域挺进。

2000 年,JDK1.3 发布,Java HotSpot Virtual Machine 正式发布,成为 Java 的默认虚拟机。

2002 年,JDK1.4 发布,古老的 Classic 虚拟机退出历史舞台。

2003 年年底,Java 平台的 Scala 正式发布,同年 Groovy 也加入了 Java 阵营。

2004 年,JDK1.5 发布。同时 JDK1.5 改名为 JavaSE5.0。

2006 年,JDK6 发布。同年,Java 开源并建立了 OpenJDK。顺理成章,Hotspot 虚拟机也成为了 openJDK 中的默认虚拟机。

2007 年,Java 平台迎来了新伙伴 Clojure。

2008 年,Oracle 收购了 BEA,得到了 JRockit 虚拟机。

2009 年,Twitter 宣布把后台大部分程序从 Ruby 迁移到 Scala,这是 Java 平台的又一次大规模应用。

2010 年,Oracle 收购了 Sun,获得 Java 商标和最真价值的 HotSpot 虚拟机。此时,Oracle 拥有市场占用率最高的两款虚拟机 HotSpot 和 JRockit,并计划在未来对它们进行整合:HotRockit

2011 年,JDK7 发布。在 JDK1.7u4 中,正式启用了新的垃圾回收器 G1。

2017 年,JDK9 发布。将 G1 设置为默认 Gc,替代 CMS

同年,IBM 的 J9 开源,形成了现在的 Open J9 社区

2018 年,Android 的 Java 侵权案判决,Google 赔偿 Oracle 计 88 亿美元

同年,Oracle 宣告 JavaEE 成为历史名词 JDBC、JMS、Servlet 赠予 Eclipse 基金会

同年,JDK11 发布,LTS 版本的 JDK,发布革命性的 ZGC,调整 JDK 授权许可

2019 年,JDK12 发布,加入 RedHat 领导开发的shenandoah GC


167151bbcfbcb07427cd8f8ba855c89f.png


在 JDK11 之前,OracleJDK 中还会存在一些 OpenJDK 中没有的、闭源的功能。但在 JDK11 中,我们可以认为 OpenJDK 和 OracleJDK 代码实质上已经完全一致的程度。


不过,主流的 JDK 8 在 2019 年 01 月之后就被宣布停止更新了。另外, JDK 11 及以后的版本也不再提供免费的长期支持(LTS),而且 JDK 15 和 JDK 16 也不是一个长期支持的版本,最新的 JDK 15 只支持 6 个月时间,到 2021 年 3 月,所以千万不要把 JDK 15 等非长期支持版本用在生产。


50b9d2358eac70ed5a1012fde69cd9c5.png


1.5. 虚拟机与 Java 虚拟机


虚拟机


所谓虚拟机(Virtual Machine),就是一台虚拟的计算机。它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。


大名鼎鼎的 Visual Box,Mware 就属于系统虚拟机,它们完全是对物理计算机的仿真,提供了一个可运行完整操作系统的软件平台。

程序虚拟机的典型代表就是 Java 虚拟机,它专门为执行单个计算机程序而设计,在 Java 虚拟机中执行的指令我们称为 Java 字节码指令。

无论是系统虚拟机还是程序虚拟机,在上面运行的软件都被限制于虚拟机提供的资源中。


Java 虚拟机


Java 虚拟机是一台执行 Java 字节码的虚拟计算机,它拥有独立的运行机制,其运行的 Java 字节码也未必由 Java 语言编译而成。(只要字节码符合规范就可执行)

JVM 平台的各种语言可以共享 Java 虚拟机带来的跨平台性、优秀的垃圾回器,以及可靠的即时编译器。

Java 技术的核心就是 Java 虚拟机(JVM,Java Virtual Machine),因为所有的 Java 程序都运行在 Java 虚拟机内部。

作用


Java 虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为对应平台上的机器指令执行。每一条 Java 指令,Java 虚拟机规范中都有详细定义,如怎么取操作数,怎么处理操作数,处理结果放在哪里。

特点


一次编译,到处运行

自动内存管理

自动垃圾回收功能

JVM 的位置


a8700228be034044a49552b45a66248c.jpg


JVM 是运行在操作系统之上的,它与硬件没有直接的交互

6bbaeab08338835ecef1ad605cc58361.png


相关文章
|
14天前
|
存储 Java 编译器
Java内存模型(JMM)深度解析####
本文深入探讨了Java内存模型(JMM)的工作原理,旨在帮助开发者理解多线程环境下并发编程的挑战与解决方案。通过剖析JVM如何管理线程间的数据可见性、原子性和有序性问题,本文将揭示synchronized关键字背后的机制,并介绍volatile关键字和final关键字在保证变量同步与不可变性方面的作用。同时,文章还将讨论现代Java并发工具类如java.util.concurrent包中的核心组件,以及它们如何简化高效并发程序的设计。无论你是初学者还是有经验的开发者,本文都将为你提供宝贵的见解,助你在Java并发编程领域更进一步。 ####
|
25天前
|
缓存 easyexcel Java
Java EasyExcel 导出报内存溢出如何解决
大家好,我是V哥。使用EasyExcel进行大数据量导出时容易导致内存溢出,特别是在导出百万级别的数据时。以下是V哥整理的解决该问题的一些常见方法,包括分批写入、设置合适的JVM内存、减少数据对象的复杂性、关闭自动列宽设置、使用Stream导出以及选择合适的数据导出工具。此外,还介绍了使用Apache POI的SXSSFWorkbook实现百万级别数据量的导出案例,帮助大家更好地应对大数据导出的挑战。欢迎一起讨论!
141 1
|
12天前
|
JavaScript 前端开发 Java
垃圾回收机制会导致内存泄漏吗?
【10月更文挑战第29天】虽然JavaScript的垃圾回收机制本身是为了有效地管理内存,但开发者在编写代码时需要注意上述这些可能导致内存泄漏的情况,遵循良好的编程习惯,及时释放不再使用的资源,以确保程序能够高效地利用内存资源,避免出现内存泄漏问题。
|
9天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
30 6
|
1月前
|
存储 监控 算法
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程 ?
尼恩提示: G1垃圾回收 原理非常重要, 是面试的重点, 大家一定要好好掌握
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程  ?
|
13天前
|
存储 缓存 安全
Java内存模型(JMM):深入理解并发编程的基石####
【10月更文挑战第29天】 本文作为一篇技术性文章,旨在深入探讨Java内存模型(JMM)的核心概念、工作原理及其在并发编程中的应用。我们将从JMM的基本定义出发,逐步剖析其如何通过happens-before原则、volatile关键字、synchronized关键字等机制,解决多线程环境下的数据可见性、原子性和有序性问题。不同于常规摘要的简述方式,本摘要将直接概述文章的核心内容,为读者提供一个清晰的学习路径。 ####
34 2
|
14天前
|
存储 安全 Java
什么是 Java 的内存模型?
Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)规范的一部分,它定义了一套规则,用于指导Java程序中变量的访问和内存交互方式。
36 1
|
21天前
|
监控 算法 Java
深入理解Java的垃圾回收机制
【10月更文挑战第22天】在Java的世界里,有一个默默无闻却至关重要的角色——垃圾回收(Garbage Collection, GC)。就像城市的清洁工一样,它默默地清理着不再使用的内存空间,确保我们的程序运行得既高效又稳定。但你真的了解垃圾回收是如何工作的吗?让我们一起探索这个看似简单却充满奥秘的过程,看看它是如何影响你的Java应用性能的。
|
20天前
|
存储 运维 Java
💻Java零基础:深入了解Java内存机制
【10月更文挑战第18天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
27 1
|
23天前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。