1.新生代+老年代+永久代(1.7Perm Generatoor)+元数据(1.8 MetaSpace)
堆之内:新生代,老年代
堆之外(方法区):永久代+元数据(主要放class文件和一些编译性的中间文件)
字符串常量:1.7之前永久代,1.8之后位于堆
永久代:必须指定限定大小,常常产生内存溢出,元数据不需要指定,也可以指定,上限取决于物理内存大小
CMS:算法:三色标记+Incremental update
G1(10ms):三色标记+SATB
ZGC(1ms)PK C++:Corlored Pointer +写屏障
Shannadoah:Corlored Pointer +读屏障
1.6,.1.7传统行业CMS(1.4之后就有了),1.7才有的G1,一般1.8才用G1,1.9默认G1
- 垃圾回收器跟内存大小的关系
1.Serial:几十兆
2.PS上百兆-几个G
3.CMS;20G
4.ZGC-4T
2.JVM常用命令参数
常见垃圾回收器组合参数设定
- -XX:++UseSerialGC(DefNew)+Serial Old
小程序型,默认情况不会选这种选项,hospot会根据计算机和配置及jdk版本自动选择收集器
- -XX:++UseConcurrentMarkSweepGC=ParNew+CMS+Serial Old
- -XX:++UseParallerlGC=Parallerl Scavange+Parallerl Old(1.8默认)
- -XX:++UseG1GC=G1(不分代)
区分概念:内存泄露memory leak和内存溢出out of memory
内存泄漏指对象用完没有回收,一直占着这块地,内存溢出是指不断产出对象,内存撑不住了,暴了
- java -XX:+PrintCommandLineFlags HelloWord
打印这个文件运行jvm的命令 行参数
- java -Xmn10M -Xms40M -Xmx60M -XX:PrintCommandLineFlags -XX PrintGC HelloWorld
设置新生代大小为10M,最小堆大小40M,最大堆大小60M,打印 这个文件运行jvm的命令 行参数,打印GC信息
- java -XX:++UseConcMarkSweepGC -XX:PrintCommandLineFlags HelloWorld
打印CMS的相关信息·
- java -XX:++PrintFlagsInital默认参数值
- java-XX:++PrintFlagsFinal最终参数值
- java-XX:++PrintFlagsFinal | grep xxx找到对应参数值
- java-XX:++PrintFlagsFinal -version| grep GC找到GC对应参数值
3.GC日志详解
java -XX:++PrintGCDetails HelloWorld(查看GC详细信息)
Time:user(用户时间),sys(内核时间),real(总时间)
内存溢出后会把heap dump部分的信息打印出来
4.JVM调优(6个步骤)
- 无监控,无场景不调优
调优需要建立在监控之上,由压力测试来判断是否达到业务要求和性能要求
根据业务具体需求场景来确定目标是吞吐量(用户代码执行时间/(GC时间+用户执行时间))还是相应时间(STW越短越好)
- 根据根据业务具体需求场景来确定目标是吞吐量还是响应时间
- 选择合适的垃圾回收器如果注重吞吐量,建议选择ps+po,如果注重相应时间(首选G1),1.8之前选(CMS+ParNew)
- 设定实际情况设置升级年龄,最大年龄15
- 选择计算内存大小(根据经验进行压测)
- 选择性能高的cpu(在已有条件下,越高越好)
- 设置日志参数,GC文件循环使用,最大为20M,5个GC文件循环使用覆盖
5.cpu使用飙高问题
说明有线程一直占据哪个资源不放,所以我们需要定位看是哪个线程?
1.使用top命令查看进程,获取使用cpu最高的进程pid,可以使用jps查看java进程
2.使用top -hp pid查看是该进程的哪个线程一直占用cpu
3.使用jstack pid 打印它的线程信息(此处需要pid10进制转16进制)
4.使用jastack分析线程信息,关注线程状态。Runnable,waiting ,wating for ,如果很多线程都在等待,那么找到是哪个线程一直在持有该资源没释放,如果只有一个在wait,那么看它在waiting for 谁,定位到相应的代码中去
6.内存一直飙高问题
说明产生的对象一直没有回收,java对象一直堆积在堆内存中,这也是所说的oom问题
- jinfo pid查看当前虚拟机信息
- jstat -gc pid ms 打印年轻代,老年代gc信息(多少秒打印一次),gc测试信息
- jmap histo pid |head 20,看看当前进程对象产生情况,最多显示20个
- jmap dump也可以产生堆存储文件,但jmap对生产环境性能音响较大,一半不这么干,可以设等-XX:++HeapDumpOutOfMemory参数,在oom时会自动生成堆内存文件,如果需要线上分析堆文件信息,可以将这台服务器下线,隔离进行分析,或者使用第三方工具,阿里的arthas。
7.图形化界面
jdk提供了 jvisualvmh和JConsoul来对进程的线程和堆进行图形化的详细分析(用于压测),但是也不适用于线上环境,因为新开服务连接会对服务器造成性能影响,或者使用阿里的图形化界面jprofile
8.JVM调优常用参数
GC通用参数
-Xmn:年青代大小
-Xms:堆初始大小
-Xmx:最大堆大小
-Xss:栈大小