问题描述:
线上的服务出现间断性不能访问,开发临时进行排查。
在应用程序部署的节点上通过:jstat -gc 进程号 1000查看程序gc的情况,发现full gc的次数很高,并持续增长很快;
打开gc的日志,发现CMCgc、fullGC频繁发生,当fullGC时,界面就不可访问了。
因为内存马上就会内存溢出了,因此重启了服务修复了该问题(当前正在服务器上运行的任务怎么办?是否有做完备的高可用方案,这个会写文档讨论)
内存:
java的内存分为堆和栈。
堆分为:新生代、老年代、持久代;
堆中存放这new出的对象,堆中放着各种在多线程中共享的变量,线程的私有变量存放在栈中;
新生代分为伊甸区、S0 、S1; Eden不足触发MinorGC ,将相关的信息放入S0中,S0不足是触发MinorGC放到S1中,当GC次数>15次后,会放入年老代,年老代空间不足就full GC了。
栈用于存放函数调度以及生成的局部变量等等,当递归调用时,容易发生栈溢出。
当大数据兴起后,java发现处理大数据太占用内存,因此为了避免内存溢出,在jdk1.8中将持久代放到了元空间,元空间的大小等于机器的内存大小。
篇头说的内存不足的情况,其实是有很多任务并发运行,并发运行的任务初始化了大量类相关信息,占用了很多的内存。
垃圾回收算法:
1、标记-清除算法 : 容易产生碎片
2、标记-整理算法 : 用于年老代GC
3、复制算法 :可用内存是原有的1/2
在我们项目中老年代使用的是CMC收集器