JVM
2020-12-26 15:22:41 20 举报
AI智能生成
JVM思维导图
作者其他创作
大纲/内容
JVM加载
加载
使用到加载.class文件
类加载器
启动类加载器 Bootstrap ClassLoader
扩展类加载器 Extension ClassLoader
应用程序类加载器 Application ClassLoader
自定义类加载器
双亲委派机制
验证
根据JVM虚拟机规范进行验证是否符合
准备
类分配一定的内存空间,类变量分配内存空间,分配默认初始值
解析
符合引用替换为实际引用
初始化
执行类的初始化代码
使用
卸载
内存区域
元数据空间(方法区)
存放类信息,常量池
程序计数器
记录执行的字节码指令位置
java虚拟机栈
栈帧
局部变量表 、操作数栈、动态链接、方法出口等
本地方法栈
堆内存
分代模型
年轻代
老年代
永久代
参数
-Xms 堆内存的最小大小
-Xmx 堆内存的最大大小
-Xmn 堆内存中的新生代大小,扣除新生代剩下的就是老年代的内存大小了
-XX:PermSize:永久代大小
-XX:MaxPermSize:永久代最大大小
-Xss:每个线程的栈内存大小
-XX:MetaspaceSize和-XX:MaxMetaspaceSize (jdk1.8)
-XX:CMSInitiatingOccupancyFaction 参数可以用来设置老年代占用多少比例的时候触发CMS垃圾回收,JDK 1.6里面默认的值是92%。
-XX:+UseCMSCompactAtFullCollection Full GC之后要再次进行“Stop the World”,停止工作线程,然后进行碎片整理,就是把存活对象挪到一起,空出来大片连续内存空间,避免内存碎片。
-XX:SurvivorRatio=8(新生代分区比例 8:2)
-XX:+UseConcMarkSweepGC(指定使用的垃圾收集器,这里使用CMS收集器)
-XX:+PrintGCDetails(打印详细的GC日志)
-XX:+UseConcMarkSweepGC(指定使用的垃圾收集器,这里使用CMS收集器)
-XX:+PrintGCDetails(打印详细的GC日志)
-XX:MaxTenuringThreshold 多少岁进入老年代,可以通过JVM参数“”来设置,默认是15岁
-XX:PretenureSizeThreshold”,直接进入老年代可以把他的值设置为字节数,比如“1048576”字节,就是1MB
-XX:CMSFullGCsBeforeCompaction”,这个意思是执行多少次Full GC之后再执行一次内存碎片整理的工作,默认是0
垃圾回收算法
复制算法
1个Eden区,2个Survivor区
老年代标记整理算法
Serial和Serial Old垃圾回收器:分别用来回收新生代和老年代的垃圾对象
ParNew和CMS垃圾回收器:ParNew现在一般都是用在新生代的垃圾回收器,CMS是用在老年代的垃圾回收器
G1垃圾回收器:统一收集新生代 和老年代
CMS
初始标记(stop the world)
并发标记
重新标记(stop the world)
并发清理
-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:PermSize=256M -XX:MaxPermSize=256M -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=5 -XX:PretenureSizeThreshold=1M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFaction=92 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0
Concurrent Mode Failure
子主题
G1垃圾回收器
Java堆内存拆分为多个大小相等的Region
G1可以做到让你来设定垃圾回收对系统的影响,他自己通过把内存拆分为大量小Region,以及追踪每个Region中可以回收的对象大小和预估时间,最后在垃圾回收的时候,尽量把垃圾回收对系统造成的影响控制在你指定的时间范围内,同时在有限的时间内尽量回收尽可能多的垃圾对象
JVM最多可以有2048个Region,然后Region的大小必须是2的倍数,比如说1MB、2MB、4MB之类的
选择最小回收时间和最多回收对象的region
-XX:G1HeapRegionSize
-XX:G1NewSizePercent
-XX:G1MaxNewSizePercent
-XX:MaxGCPauseMills
比如年龄为1岁,2岁,3岁,4岁的对象的大小总和超过了Survivor的50%,此时4岁以上的对象全部会进入老年代,这就是动态年龄判定规则
Xms4096M -Xmx4096M -Xss1M -XX:PermSize=256M -XX:MaxPermSize=256M
jstat
jstat -gccapacity PID:堆内存分析
jstat -gcnew PID:年轻代GC分析,这里的TT和MTT可以看到对象在年轻代存活的年龄和存活的最大年龄
jstat -gcnewcapacity PID:年轻代内存分析
jstat -gcold PID:老年代GC分析
jstat -gcoldcapacity PID:老年代内存分析
jstat -gcmetacapacity PID:元数据区内存分析
jstat -gc 11387 1000 10
jmap
使用jmap了解系统运行时的内存区域
jmap -heap PID
S0C 年轻代中第一个 survivor 的容量
S1C 年轻代中第二个 survivor 的容量
S0U 年轻代中第一个 survivor 目前已使用空间
S1U 年轻代中第二个 survivor 目前已使用空间
EC 年轻代中 Eden 的容量
EU 年轻代中 Eden 目前已使用空间
OC 老年代的容量
OU 老年代目前已使用空间
MC 元空间 metaspace 的容量
MU 元空间 metaspace 目前已使用空间
YGC 从应用程序启动到采样时 年轻代 中 gc 次数
YGCT 从应用程序启动到采样时 年轻代 中 gc 所用时间
FGC 从应用程序启动到采样时 老年代 中 gc 次数
FGCT 从应用程序启动到采样时 老年代 中 gc 所用时间
GCT 从应用程序启动到采样时 gc 用的 总时间
CCSC 压缩类空间大小
CCSU 压缩类空间 使用 大小
https://www.cnblogs.com/ostenant/p/9696226.html
jmap -histo PID
jmap -dump:live,format=b,file=dump.hprof PID
jhat
使用jhat在浏览器中分析堆转出快照
jhat dump.hprof -port 7000
优化思路
尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。
-XX:NewSize=104857600 -XX:MaxNewSize=104857600 -XX:InitialHeapSize=209715200 -XX:MaxHeapSize=209715200 -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15 -XX:PretenureSizeThreshold=3145728 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
-XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5
CMS垃圾回收器默认是采用标记-清理算法,所以是会造成大量的内存碎片的。
5次full gc之后进行压缩
JVm参数模板
-Xms4096M -Xmx4096M -Xmn3072M -Xss1M -XX:PermSize=256M -XX:MaxPermSize=256M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFaction=92 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSParallelInitialMarkEnabled 这个参数会在CMS垃圾回收器的“初始标记”阶段开启多线程并发执行
初始标记阶段,是会进行Stop the World的,会导致系统停顿,所以这个阶段开启多线程并发之后,可以尽可能优化这个阶段的性能,减少Stop the World的时间
-XX:+CMSScavengeBeforeRemark”,这个参数会在CMS的重新标记阶段之前,先尽量执行一次Young GC
-XX:TraceClassLoading -XX:TraceClassUnloading 这两个参数,顾名思义,就是追踪类加载和类卸载的情况,他会通过日志打印出来JVM中加载了哪些类,卸载了哪些类。
实际上一旦这个参数设置为0之后,直接导致clock - timestamp <= freespace * SoftRefLRUPolicyMSPerMB这个公式的右半边是0,就导致所有的软引用对象,比如JVM生成的那些奇怪的Class对象,刚创建出来就可能被一次Young GC给带着立马回收掉一些。
-XX:+DisableExplicitGC。这个参数的意思就是禁止显式执行GC,不允许你来通过代码触发GC System.gc()
OOM
Metaspace区域里就会发生OOM
-XX:MetaspaceSize=512m
cglib动态分配类容易发生
-XX:MaxMetaspaceSize=512m
虚拟机栈发生OOM
递归调用方法发容易发生
堆内存发生OOM
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/usr/local/app/oom
-Xms4096M -Xmx4096M -Xmn3072M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFaction=92 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSParallelInitialMarkEnabled -XX:+CMSScavengeBeforeRemark -XX:+DisableExplicitGC -XX:+PrintGCDetails -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/app/oom
0 条评论
下一页