深入理解JVM内存管理:从区域划分到优化策略

JVM内存区域划分有哪些?

堆内存:分为新生代和老年代

新生代:临时对象,所有对象最开始都是年轻代,使用完会被回收或转入老年代

老年代:长期存在的对象

进入老年代的情况:

1.新生代垃圾回收超过15次还没有回收掉就转入老年代

2.大对象(-XX:PretenureSizeThreshold参数设置分界,单位字节)直接从新生代进入老年代

3.动态年龄判断 年龄1+年龄2+年龄n的多个年龄对象综合超过了Survivor区域的50%,就会把年龄n以上的对象都放入老年代

4.Eden区存活对象大于Survivor区时直接转移到老年代去

元数据区:内存的永久保存区域,主要存放class和meta(元数据)的信息

线程虚拟机栈:每一次请求都会开一个虚拟机栈

GCOOM的联系和区别?

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值