1.GC问题
控制台 jconsole
配置远程连接
java -Djava.rmi.server.hostname=ip -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=3214 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar xxx.jar
-XX:MetaspaceSize=265M -Xmn768m -Xmx2048m -Xms2048m
打印内存状态
第一种
jmap -histo pid 不是很会用
第二种
jstat -gc 9293 5000 20
S0C:年轻代第一个survivor的容量(字节)
S1C:年轻代第二个survivor的容量(字节)
S0U:年轻代第一个survivor已使用的容量(字节)
S1U:年轻代第二个survivor已使用的容量(字节)
EC:年轻代中Eden的空间(字节)
EU:年代代中Eden已使用的空间(字节)
OC:老年代的容量(字节)
OU:老年代中已使用的空间(字节)
MC:当前元数据空间大小
MU:当前已用的元数据空间
CCSC: 压缩类空间
CCSU
YGC:从应用程序启动到采样时年轻代中GC的次数
YGCT:从应用程序启动到采样时年轻代中GC所使用的时间(单位:S)
FGC:从应用程序启动到采样时老年代中GC(FULL GC)的次数
FGCT:从应用程序启动到采样时老年代中GC所使用的时间(单位:S)
GCT
jvm回收原理
就拿1.8为例
首先是java内存 主要分两个区 堆区和非堆区
堆区 一般都放对象 同理 非堆区一般用于类 常量 或者方法
新生代,metaspace 老年代 三大数据区
什么时候回收?
有几种方式,首先 你可以手动回收,就是使用 System.gc();
第二种 垃圾回收机制,我们知道在jvm中之前说了 在堆区中一个新生代和老年代 新生代分为两个区 一个叫Eden space 还有一个叫survivor space s0 和s1
To Survivor 和 From Survivor的标记会互换,始终保证一个survivor是空的。
减少碎片 类似复制算法
新生代的的垃圾收集动作,Minor GC 非常频繁,回收速度一般也比较快。 在eden区满时进行回收
full GC 升到老年代的对象大于老年代剩余空间full gc,或者小于时被HandlePromotionFailure参数强制full gc
对什么回收?
不可达对象 或者是计数0 对象
怎么回收
回收算法
为什么jvm内存回收了 但是服务器没有free到内存呢?
猜测的几点考虑
1.对象回收需要引用计数或者对象不可达,需要扫描整个堆内存,那么导致接触一次对象就要扫描内存 把对应的内存块还回去
2.避免频繁的向操作系统申请资源
3.效率 避免归还 产生大量的内存碎片
jvm 调优参数
Xms 最大可使用内存
Xmx 最大堆内存
-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值