GC(Garbage Collection)
内存简图
- jvm内存分为堆内存和非堆内存,堆内存分为年轻代、老年代,非堆内存里只有个永久代。
- 年轻代分为生成区(Eden)和幸存区(Survivor),幸存区由FromSpace和Tospace两部分组成,默认情况下,内存大小比例:Eden:FromSpace:ToSpace 为 8:1:1。
- 堆内存存放的是对象,垃圾收集器回收的就是这里的对象,不同区域的对象根据不同的GC算法回收,比如年轻代对应Minor GC,老年代对应Major GC。
- 非堆内存即永久代,也称为方法区,存储的是程序运行时长期存活的对象,比如类的元数据、方法、常量、属性等。
- 在jdk1.8废弃了永久代,使用元空间(MetaSpace)取而代之,元空间存储的对象与永久代相同,区别是:元空间并不在jvm中,使用的是本地内存。
分代
新生成的对象首先存放在生成区,当生成区满了,触发Minor GC,存活下来的对象转移到Survivor0,即FromSpace,Survivor0区满后触发执行Minor GC,存活对象移动到Suvivor1区,即ToSpace,经过多次Minor GC仍然存活的对象转移到老年代。
所以老年代存储的是长期活动的对象,当老年代满了会触发Major GC。
Minor GC和Major GC是俗称,有些情况下Major GC和Full GC是等价的,如果出发了Full GC,那么所有线程必须等待GC完成才能继续(见GC分类和算法)。
分代原因
将对象根据存活概率进行分类,对存活时间长的对象,放到固定区,从而减少扫描垃圾时间及GC频率。针对分类进行不同的垃圾回收算法,对算法扬长避短。
JVM参数
如果内存设置小了,整个系统经常gc,会导致程序变慢。
-Xss:每个线程的栈大小
-Xms:初始堆大小,默认物理内存的1/64
-Xmx:最大堆大小,默认物理内存的1/4
-Xmn:新生代大小
-XX:NewSize:设置新生代初始大小
-XX:NewRatio:默认2表示新生代占年老代的1/2,占整个堆内存的1/3。
-XX:SurvivorRatio:默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。
-XX:MetaspaceSize:设置元空间大小
-XX:MaxMetaspaceSize:设置元空间最大允许大小,默认不受限制,JVM Metaspace会进行动态扩展。
配置参数
-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC
JDK8之后把-XX:PermSize 和 -XX:MaxPermGen移除了,取而代之的是-XX:MetaspaceSize=128m(元空间默认大小)-XX:MaxMetaspaceSize=128m(元空间最大大小)
命令分析
查看进程
jps -l
-l
代表的是输出应用程序main class的完整package名或者应用程序的jar文件完整路径名
查看JVM参数
jinfo -flags <端口号>
查看对象及内存使用情况
jmap -histo <端口号> > ./log.tx
内存溢出分析
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/Users/fanshaorong/Desktop/logs/jvmlogs/jvm.jump
文件->装入
调优的目标
-
减少停顿时间:垃圾收集器做垃圾回收中断应用执行的时间。 可以通过
-XX:MaxGCPauseMillis
参数进行设置,以毫秒为单位,至少大于1 -
提高吞吐量:垃圾收集的时间和总时间的占比:1/(1+n),吞吐量为1-1/(1+n) 。通过
-XX:GCTimeRatio=n
参数进行设置,99的话代表吞吐量为99%
调优步骤
-
打印GC日志
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps
-Xloggc:./gc.log
-
分析日志
-
修改参数验证结果
-XX:MetaspaceSize=128m(元空间默认大小)
-XX:MaxMetaspaceSize=128m(元空间最大大小)
-Xms1024m(堆最大大小)
-Xmx1024m(堆默认大小)
-Xmn256m(新生代大小)
-Xss256k(棧最大深度大小)
-XX:SurvivorRatio=8(新生代分区比例 8:2)
-XX:+UseConcMarkSweepGC(指定使用的垃圾收集器,这里使用CMS收集器)
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/Users/fanshaorong/Desktop/logs/jvmlogs/jvm.jump (错误输出地址)
-XX:+PrintGCDetails(打印详细GC日志)
-XX:+PrintGCTimeStamps:打印GC时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps:打印GC时间戳(以日期格式)
-Xloggc(打印gc日志地址)