JVM内存区域划分有哪些?
堆内存:分为新生代和老年代
新生代:临时对象,所有对象最开始都是年轻代,使用完会被回收或转入老年代
老年代:长期存在的对象
进入老年代的情况:
1.新生代垃圾回收超过15次还没有回收掉就转入老年代
2.大对象(-XX:PretenureSizeThreshold参数设置分界,单位字节)直接从新生代进入老年代
3.动态年龄判断 年龄1+年龄2+年龄n的多个年龄对象综合超过了Survivor区域的50%,就会把年龄n以上的对象都放入老年代
4.Eden区存活对象大于Survivor区时直接转移到老年代去
元数据区:内存的永久保存区域,主要存放class和meta(元数据)的信息
线程虚拟机栈:每一次请求都会开一个虚拟机栈
GC 和OOM的联系和区别?
GC分为Young GC和Full GC
young GC是指进行年轻代的垃圾回收
Full GC是指新生代、老年代、元数据区的所有回收,STW(stop the world)
OOM是在Full GC之后还是内存不足触发的
垃圾回收器和垃圾回收机制有哪些?哪种更好?为什么?
Serial(串行GC)-复制算法,单个GC线程实现
Serial Old(MSC)(串行GC)-标记-整理,单个GC线程实现
JDK1.3.1默认使用,Serial和Serial Old都会暂停所有用户线程,JVM使用-XX:UseSerialGC设置使用,适用于CPU核数<2,物理内存<2G的小型应用程序
Parallel Scavenge(并行回收GC)-复制算法,多线程实现
Parallel Old(并行GC)--标记-整理算法,多线程实现
JDK1.6~1.8默认使用,JVM使用-XX:+UseParallelOldGC设置使用,Parallel Scavenge和Parallel Old都会暂停所有用户线程,吞吐量优先
ParNew(并行GC)-复制,多线程实现
CMS(并发GC)-标记-清除,多线程实现
JVM使用-XX:+UseConcMarkSweepGC设置使用,分为四个阶段初始标记(STW)、并发标记、重新标记(STW)、并发清理,STW时间减少了
G1
回收分为初始标记、并发标记、最终标记、筛选回收
JDK1.9默认使用,相较于CMS和ParNew垃圾回收之后会整合内存空间,减少内存碎片
ZGC
JDK11推出的垃圾回收器,GC停顿可以在10ms内,支持TB级别内存
JVM的核心参数有哪些?
-Xms Java堆内存的最小大小 通常和Xmx设置一样,?
-Xmx Java堆内存的最大大小 一般为操作系统的2/3大小 ?
-Xss 每个线程的栈内存大小 默认1m,一般不进行设置 ?
-Xmn Java堆内存中的新生代大小,扣除新生代剩下的就是老年代的内存大小了 默认新生代占堆大小的1/3 G1下不建议设置会按需扩大和缩小年轻代 ?
-XX:MetaspaceSize 永久代大小 一般设置几百M 通常和-XX:MaxMetaspaceSize设置一样?
-XX:MaxMetaspaceSize 永久代最大大小 程序项目越大需要越大 一般为256M
-XX:+UseG1GC 启用G1垃圾收集器
-XX:SurvivorRatio=8 Eden区的比例,默认为80% 可以不调整
-XX:+PrintGCDetails 打印详细的GC日志
-XX:PretenureSizeThreshold 大对象阀值,单位字节,不建议设置,默认第一次都是进入新生代 ?
-XX:+PrintGCTimeStamps 打印出来每次GC消耗的时间
-Xloggc:gc.log 参数可以设置将gc日志写入一个磁盘文件 ?
-XX:+HeapDumpOnOutOfMemoryError 在OOM的时候自动dump内存快照出来
-XX:HeapDumpPath=path路径 把内存快照放到哪儿去 可以使用MAT工具进行分析 ?
-XX:+DisableExplicitGC 参数的意思就是禁止显式执行GC,不允许你来通过代码触发GC ?
-verbose:gc 加载打印类的详细信息
优化JVM需要优化什么?
目标:
1.尽可能让对象都在新生代里分配和回收
2.尽量别让太多对象频繁进入老年代
3.避免频繁对老年代进行垃圾回收
4.给系统充足的内存大小
5.避免新生代频繁的进行垃圾回收
如何查看JVM内存划分?
查看各个区域大小
找到java程序的pid
jps -v
jstat -gc [PID] 1000 1
jstst -gcutil [PID]
查看默认使用的垃圾回收器
java -XX:+PrintCommandLineFlags -version
如何通过命令观察JVM运行情况?如何监控JVM运行情况?
sudo jstat -gc PID 1000 10 每隔1秒钟更新出来最新的一行jstat统计信息,一共执行10次jstat统计
sudo jstat -gcutil PID
jstat -gccapacity PID 堆内存分析
jstat -gcnew PID 年轻代GC分析,这里的TT和MTT可以看到对象在年轻代存活的年龄和存活的最大年龄
jstat -gcnewcapacity PID 年轻代内存分析
jstat -gcold PID 老年代GC分析
jstat -gcoldcapacity PID 老年代内存分析
jstat -gcmetacapacity PID 元数据区内存分析
jmap -heap PID 查看堆内存使用情况
jmap -histo PID 会按照各种对象占用内存空间的大小降序排列,把占用内存最多的对象放在最上面
jmap -dump:format=b,file=文件名 [服务进程ID] 用jmap命令导出一份线上系统的内存快照
Zabbix采集 + grafana图形化显示工具
MAT 内存分析工具 排查大内存
发生OOM之后如何快速定位问题?
实操JVM引发OOM程序
📎jvm-learn.zip
实践积加生产环境JVM优化
https://jijiaerp.feishu.cn/wiki/wikcnRusgmipVTtOz1F7xtGOtOf
https://jijiaerp.feishu.cn/wiki/wikcngxZRaM7zB0CiJPJvijDRYg
https://jijiaerp.feishu.cn/wiki/wikcnD5Ax5zsN0gm6xOFl1Lrgzd