1.1什么是JVM
1.1.1 概念
JVM一般指Java虚拟机,虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的,Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
1.1.2 Java内存结构
JVM的内存结构大致分为五个部分,分别是程序计数器、虚拟机栈、本地方法栈、堆和方法区。除此之外,还有由堆中引用的JVM外的直接内存。
程序计数器:保存当前执行指令的地址,一旦指令执行,程序计数器将更新到下一条指令
虚拟机栈:每个线程运行时所需要的内存空间,称为虚拟机栈;每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存;每个线程只有一个活动栈帧,对应着当前正在执行的那个方法。
本地方法栈:被native修饰的方法就是本地方法,本地方法栈的功能特点类似于虚拟机栈,也是线程私有的。不同的是:本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM执行的Java方法
堆:创建的对象、 new 创建 数组存放在堆内存。(堆所有线程会被共享)
采用元空间而不用永久代的原因:
- 为了解决永久代的OOM问题,元数据和class对象存放在永久代中,容易出现性能问题和内存溢出。
- 类及方法的信息等比较难确定其大小,因此对于永久代大小指定比较困难,大小容易出现永久代溢出,太大容易导致老年代溢出(堆内存不变,此消彼长)。
- 永久代会为GC带来不必要的复杂度,并且回收效率偏低。
- 新生代:
①Edn区:刚创建的
② **S0:**与S1大小相当,目的是垃圾回收机制复制算法
③ S1:
老年代:如果对象频繁使用,则放入老年代

- 方法区(永久):static关键字修饰,常量信息当class加载时,就会被初始化(不要定义太多的常量,方法区中所有线程共享,注意线程安全问题)。
1.1.3 Jvm1.8部分参数
-Xcomp:在第一次调用时强制编译方法
-Xloggc:filename.log:设置应将重定向的GC事件信息重定向到的文件以进行日志记录
-Xmaxjitcodesize = size:指定JIT编译代码的最大代码高速缓存大小(以字节为单位)
-Xmixed:除了热方法之外,解释器执行所有字节码,热方法被编译为本机代码。
-Xmx size:指定内存分配池的最大大小
-Xms size:设置堆初始大小
-Xmn size:设置年轻代堆初始和最大大小内存(以字节为单位)。附加字母k或K表示千字节,m或M指示兆字节,g或G指示千兆字节。
-Xss size:设置每个线程堆栈大小(以字节为单位)
1.1.4 Jvm参数调优
在JVM启动参数中,可以设置跟内存、垃圾回收相关的一些参数设置,默认情况不做任何设置JVM会工作的很好,但对一些配置很好的Server和具体的应用必须仔细调优才能获得最佳性能。通过设置我们希望达到一些目标:
- GC的时间足够的小
- GC的次数足够的少
- 发生Full GC的周期足够的长
前两个目前是相悖的,要想GC时间小必须要一个更小的堆,要保证GC次数足够少,必须保证一个更大的堆,我们只能取其平衡。
- 在web系统中,尽量减少常量信息和垃圾回收机制,新生代回收次数比老年代多
- 一般可以通过-Xms -Xmx限定其最小、最大值,我们通常把最大、最小设置为相同的值
- 设置新生代与老年代的回收比例(1/3或1/4)
Linux系统下调试JVM参数
[root@LOCAL~]#java -Xmx512m -Xms512m -Xmn256m -Xss1m –jar hello.jar
2.1GC回收机制
2.1.1 概念
不定时去堆内存清理不可达对象(可syste.mGc()进行通知系统回收,回收前执行finalize方法)
内存溢出:项目需要3g,但内存只有2g
内存泄露:对象已经没有被引用,但垃圾回收器无法移除,定义太多静态变量,占用过多,垃圾无法进行回收。
2.1.2 GC算法
引用计数法:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时减1,当为零时,垃圾回收器将回收该对象使用的内存。
- 优缺点:可以很快的执行,交织在程序运行中,对程序需要不被长时间打断的实时环境较有利。 无法检测出循环引用,如父对象引用子对象,子对象反过来引用父对象,则计数器永远不为0.
复制算法(用于新生代,每次保证一个区存活):new 的对象存放edn区,频繁使用的对象进入s0区,当这块内存使用完后,会先将存活对象复制到s1区,然后清空s0区,后续对象进入s1,往复进行。
- 优缺点:不需考虑碎片化问题,只需要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效,缺点是可使用内存降为原来一半。
标记清除法:就是先标记那些活动的对象,然后再遍历堆,所有非标记对象都是需要清除清除的对象
- 优缺点:碎片化,效率慢。
标记压缩法:在标记清除基础上做了优化,将存活对象压缩至内存的一端,而后进行垃圾清理。(中老年代使用的就是标记压缩法)
- 优缺点:连续不产生碎片化。
分代算法:根据分代选择不同算法。
2.1.3 垃圾回收时的停顿现象
目的是为了暂停所有应用程序,这样系统才不会产生新垃圾,保证了系统状态某一瞬间的一致性
2.1.4 垃圾收集器
垃圾收集器:是JVM中三个重要模块之一(解释器和多线程机制),为应用程序提供内存的自动分配、自动回收功能,这两个操作发生在Java堆上(一段内存块)。某一时刻如果有一个以上引用指向它,则为LIVE,否则死亡。
串行回收器(Serial Collector):单线程指向回收操作,client模式下的默认回收器,通过-XX:+UseSerrialGC命令行可强制指定。
并行回收器(ParNew回收器):ParNew回收器是工作在新生代的垃圾收集器,只是简单的将串行回收器多线程。