线程共享: 堆、方法区
线程独享:栈、程序计数器、本地方法栈
JVM调优主要是针对JVM参数
调优指标:吞吐量、延迟或者响应时间、内存占用
JVM调优工具
JVM调优时机
1.系统吞吐量与响应性能不高或者下降
2.Heap内存老年代持续上涨达到设置的最大内存值
3.Full GC次数频繁
4.GC停顿时间过长超过1s
5.应用程序出现OutOfMemmory等内存溢出
6.应用程序中使用本地缓存占用大量的内存空间
JVM调优目标
更少的内存
减少GC频率和次数
比如常用的:
堆内存使用率 <=75%
老年代内存使用率<=70%
avgpause<=1秒
FullGC 次数0或者 avg pause interval >=24小时
年轻代设置
避免年轻代过小 minnor GC次数频繁 二是:导致minor GC对象直接进入老年代。当老年代内存不足时候触发FullGC
避免年轻代设置过大 当新生代过大时候回带来两个问题:
一是:老年代变小 可能导致full GC频繁进行
二是:minor GC执行回收时间会大幅增加
JVM调优步骤
1.分析GC日志以及dump文件,判断是否需要优化。确定瓶颈问题点,监控JVM使用情况。包括阿里的arthas或者jconsole查看运行的状态
如何生成GC日志
-XX:+PrintGC可以创建基本的GC日志 默认情况下是关闭的 使用-XX:+PrintGcDetails会创建更加详细的GC日志 这个标志默认情况下也是关闭的;通常情况下我们使用GC日志很难诊断垃圾回收时发生的问题
如何产生dump文件
1.JVM的配置文件中配置 jvm启动时候添加两个参数
出现OOME 时生成堆dump
-XX:+HeapDumpOnOutOfMemmoryError
生产堆文件地址
-XX:HeapDumpPath=/opt/dump/
2.通过jmap生产
jmap -dump:file=文件名.dump pid
jmap -dump:format=b,file=dump.dat 9357
由于第一种方式是事后方式,需要等待jvm出现问题时候才能产生dump文件 实时性不高
第二种方式执行时候jvm暂停服务 对线上无法运行产生影响 一般可以摘取流量进行 dump
判断
如果各项参数合理,系没有没有超时日志出现、GC频率不高、GC耗时不高 那么没有必要GC优化
如果GC超过1-3秒 或者GC频繁 就需要做GC优化
调整参数
调优议案是内存需求开始 之后是延迟 最后才是吞吐量的要求 基于这个步骤进行不断优化 每一个步骤就是下一步的基础 不能逆行 重复以上的步骤 对比前后指标差异
后续跟踪指标是否正常