jvm知识点总结大全
在本文中,我将对JVM的相关知识进行总结,包括其工作原理、内存模型、垃圾回收机制、类加载机制等方面,为读者提供一个全面的了解。
jvm调优参数一、JVM的工作原理
1.1 类加载过程
当Java程序被运行时,JVM会先将程序的字节码加载到内存中,然后执行。类加载过程包括加载、连接和初始化三个阶段。
- 加载阶段:当程序使用一个类时,JVM会尝试加载这个类。如果这个类还没有被加载过,JVM会调用类加载器来加载它。类加载器首先会查.class文件,然后将文件中的字节码加载到内存中。
- 连接阶段:连接阶段包括验证、准备和解析三个步骤。在验证阶段,JVM会检查字节码是否符合Java语言规范。在准备阶段,JVM会为类变量分配内存,并设置默认初始值。在解析阶段,JVM会将类、接口、字段和方法的符号引用替换为直接引用。
- 初始化阶段:在初始化阶段,JVM会执行类的静态代码块,并初始化类变量。如果类的初始化是由其他类初始化引起的,JVM会先初始化其他类。
1.2 类的运行时数据区
JVM中包括方法区、堆、虚拟机栈、本地方法栈和程序计数器五个区域。
- 方法区:用于存储类的结构信息、运行时常量池、静态变量、常量以及编译后的代码等。方法区是线程共享的。
- 堆:用于存储对象实例以及数组。堆是Java中所有线程共享的一块内存区域。堆是垃圾回收的主要区域。
- 虚拟机栈:每个线程都有一个私有的栈,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。虚拟机栈是线程私有的,当线程创建时就被创建。
- 本地方法栈:与虚拟机栈类似,本地方法栈用于支持native方法,它也是线程私有的。
- 程序计数器:用于记录Java程序当前执行的字节码指令地址。程序计数器是线程私有的。
1.3 字节码执行引擎
JVM的字节码执行引擎负责将字节码转换为机器码并执行。它包括解释执行和即时编译两种执行模式。
- 解释执行:字节码执行引擎解释执行每一条字节码指令,逐条执行指令。这种执行模式简单,但性能较低。
- 即时编译:字节码执行引擎将热点代码(被频繁执行的代码)编译成本地机器码,以提高性能。即时编译需要耗费额外的时间和内存,但可以显著提高程序的执行速度。
二、JVM的内存模型
2.1 Java堆内存
Java堆内存是JVM中最大的一块内存区域,主要用于存储对象实例和数组。Java堆内存可以被所有线程共享,是垃圾回收的主要区域。Java堆内存可以分为新生代、老年代和永久代(在JDK 1.7版本之前)或者元空间(在JDK 1.8版本之后)。
-
新生代:新生代分为Eden区、From Survivor区和To Survivor区。大多数对象都是在新生代中创建,通过垃圾回收器的不同策略,对不同年龄段的对象进行不同的处理,达到“回收短命对象、保留长寿对象”的目的。
- 老年代:老年代主要存放经过多次垃圾回收仍然存活的对象。
- 永久代/元空间:永久代用于存储类、方法和常量等相关信息,而元空间则是在JDK 1.8版本中取代了永久代。
2.2 方法区
方法区用于存储类的结构信息、运行时常量池、静态变量、常量以及编译后的代码等。方法区是线程共享的,它可以包括类的元数据信息、类变量、常量池、方法体等。
2.3 虚拟机栈
虚拟机栈用于存储局部变量表、操作数栈、动态链接、方法出口等信息,它是线程私有的。虚拟机栈不同于方法区,它用于支持方法的调用和执行。
2.4 本地方法栈
本地方法栈与虚拟机栈类似,也是线程私有的,用于支持native方法的执行。本地方法栈中每个栈帧包含了native方法的情况。
2.5 程序计数器
程序计数器用于记录Java程序当前执行的字节码指令地址,它是线程私有的。程序计数器会在线程切换时被重置为新线程的下一条指令。
2.6 内存分配与回收策略
在JVM中,对象的内存分配一般包括新生代和老年代两个阶段。对于新创建的对象,JVM会将其分配到新生代的Eden区,并通过垃圾回收器的不同策略,对不同年龄段的对象进行不同的处理。
垃圾回收主要包括标记-清除、复制、标记-整理等算法。其中复制算法和标记-整理算法常用于新生代和老年代的垃圾回收。在新生代中,复制算法将存活的对象复制到To Survivor区,
并清空Eden区和From Survivor区。而在老年代中,标记-整理算法将存活的对象向一端移动,并清除边界外的内存块。
JVM中的垃圾回收器有很多种,包括串行垃圾回收器、并行垃圾回收器、CMS垃圾回收器、G1垃圾回收器等。每种垃圾回收器都有不同的特点和适用场景。
三、JVM的类加载机制
3.1 类加载器的层次结构
JVM中的类加载器分为三种,包括启动类加载器、扩展类加载器和应用程序类加载器。其中扩展类加载器和应用程序类加载器统称为系统类加载器。
- 启动类加载器:用于加载JRE/lib下的核心类库,它是最顶层的类加载器,由C++实现。
- 扩展类加载器:用于加载JRE/lib/ext下的扩展类库,它是Java实现。
- 应用程序类加载器:用于加载应用程序类路径上的类库。
3.2 双亲委派模型
JVM中的类加载器采用了双亲委派模型,即每个类加载器在加载类之前会先委派给其父类加载器加载。当一个类加载器收到加载类的请求时,它会先检查是否已经加载过了这个类,如果是则直接返回,否则将加载请求委派给其父类加载器。父类加载器也会按照同样的流程处理加载请求,直到引导类加载器。如果所有父类加载器都无法加载这个类,子类加载器才会自己尝试加载。
双亲委派模型的好处是能够保证类的唯一性,在JVM中不同类加载器加载的同一类也是同一个类。
3.3 类加载器的特点
在JVM中,类加载器的特点主要包括以下几点:
- 双亲委派:类加载器采用双亲委派模型,能够保证类的唯一性。
- 破坏双亲委派:有时候我们需要自定义类加载器加载特定的类,这时需要破坏双亲委派,通过重写loadClass()方法来实现。
-
类加载的时机:类加载器在加载类时采用了“懒加载”的方式,即只有在需要使用这个类的时候才加载。这也是为什么类加载器在加载类的时候不会出现重复加载的情况。
四、JVM性能调优
4.1 JVM调优工具
JVM性能调优主要包括调整堆内存大小、选择垃圾回收器、调整垃圾回收的参数、调整线程栈的大小等。在进行性能调优时,可以使用JVM自带的诊断工具,如jps、jstat、jmap、jstack、jconsole、visualvm等。
- jps:显示虚拟机进程
- jstat:查看虚拟机统计信息
- jmap:查看堆内存使用情况
- jstack:查看线程快照
- jconsole:图形界面查看虚拟机性能
- visualvm:图形化的界面显示虚拟机信息
4.2 JVM性能调优的一般步骤
在进行JVM性能调优时,一般分为以下几个步骤:
- 分析程序的性能瓶颈,包括CPU占用、内存使用、垃圾回收等。
- 使用JVM诊断工具进行性能调优。
- 根据分析结果,对JVM的各个参数进行调整,优化程序的性能。
4.3 JVM性能调优的一般策略
在进行JVM性能调优时,可以根据程序的特点和运行环境,采取以下一些常见的策略:
- 调整堆内存的大小,根据程序的特点和内存的使用情况,调整新生代和老年代的大小。
- 选择合适的垃圾回收器,根据程序的内存分配模式选择合适的垃圾回收器。
- 调整垃圾回收的参数,包括新生代和老年代的垃圾回收的频率、空间大小等。
- 调整线程栈的大小,根据程序的线程使用情况和栈内存的使用情况,调整线程栈的大小。
五、JVM的安全性
5.1 JVM的安全沙箱
JVM的安全沙箱是指JVM通过沙箱技术来限制Java程序对本地资源的访问,从而保证Java程序的安全性。JVM安全沙箱包括字节码验证、类加载机制、安全管理器等。
- 字节码验证:在加载字节码的过程中,JVM会对字节码进行验证,检查是否符合Java语言规范。只有通过验证的字节码才能被加载。
- 类加载机制:JVM采用双亲委派模型来保证类的唯一性,确保不同类加载器加载的同一类也是同一个类。
- 安全管理器:JVM提供了安全管理器来控制对本地资源的访问,程序需要通过安全管理器来获取访问本地资源的权限。
5.2 JVM的安全性机制
JVM的安全性机制主要包括以下几个方面:
- 类加载机制:JVM采用双亲委派模型来保证类的唯一性。
- 字节码验证:JVM在加载字节码的过程中会对字节码进行验证,确保其符合Java语言规范。
- 安全管理器:JVM提供了安全管理器来控制对本地资源的访问,程序需要通过安全管理器来获取访问本地资源的权限。
5.3 JVM的安全性策略
在进行JVM的安全性保护时,可以根据程序的特点和运行环境,采取以下一些常见的策略:
- 根据程序的安全要求,对访问本地资源的权限进行限制。
- 对Java程序的访问权限进行控制,确保程序只能访问其需要的资源。
- 对程序的输入进行合法性检查,避免恶意输入对程序的影响。
六、JVM的新特性
6.1 JVM 1.8版本的新特性
JVM 1.8版本带来了许多新特性,包括永久代被元空间取代、JIT编译器的新特性、垃圾回收器的改进等。
- 元空间:JVM 1.8版本中取代了永久代,元空间不再由虚拟机内存控制,而是直接使用本地内存。这样可以避免了内存溢出和内存泄漏问题,提高了内存的利用率。
- JIT编译器:JVM 1.8版本中引入了JIT编译器的新特性,能够更加有效地进行代码优化和性能提升。
- 垃圾回收器:JVM 1.8版本中对垃圾回收器进行了改进,增加了G1垃圾回收器,提高了内存的利用率和垃圾回收的效率。
6.2 JVM 11版本的新特性
JVM 11版本进一步增进了对Java程序的性能、可用性和安全性。它引入了一系列新特性,
包括ZGC垃圾回收器、Epsilon垃圾回收器、类数据共享、单线程垃圾回收器等。
- ZGC垃圾回收器:JVM 11版本中引入的ZGC垃圾回收器能够更好地满足大型内存和低延迟要求的程序。
- Epsilon垃圾回收器:JVM 11版本中引入了Epsilon垃圾回收器,用于对比其他垃圾回收器的性能。
- 类数据共享:JVM 11版本中引入了类数据共享,能够更好地提高程序的启动速度和内存利用率。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。