1. 堆内存分配
老年代2/3, 新生代1/3。其中,新生代可以分为1个eden区及2个servival区(from和to,各占新生代的1/10, 并且始终有一个区域空闲,轮流使用)
2. 存放对象
新生代:短期小对象直接存放于新生代中, 经过MinorGC,会将使用中的对象存放到其中一块servival中。多次MinorGC(默认15次,参数 -XX:MaxTenuringThreshold 可以来设定 )后仍然存活的对象进入老年代中;
老年代:1. 新生代中迭代过后存活的对象; 2. 大对象跳过新生代直接存入老年代。
jstat -gcutil 236 1000 //236为pid, 1000为打印间隔单位ms
S0、S1:两个servival区
E:新生代百分比
O:老年代百分比
M:元数据区使用比例
CCS:压缩使用比例
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
更多jstat命令及参数,参考:jstat命令查看jvm的GC情况 (以Linux为例)_ITPUB博客
3. 堆回收gc
GC分为MinorGC和FullGC(MajorGC)。MinorGC为新生代GC,特点:频繁,回收速度快;FullGC为老年代GC,回收时间较MinorGC相比也多很多(参看下图),并且伴随长时间卡顿(可达性分析会导致所有Java线程停顿),同时发生FullGC的同时一般也会伴随一次MinorGC。
4. 引用判定方法
a. 引用计数算法
对象引用计数+1, 引用失效计数-1;缺点:相互引用的时候无法回收。
b. 可达性分析算法(主流商用语言Java,C#)
GcRoots到一个对象无引用链的时候,视为不可达。
GcRoot节点主要包括:
1). 虚拟机栈中的对象
2). 方法去中静态属性引用对象
3). 方法区中常量引用的对象
4). 本地方法栈中native方法引用的对象
5. 方法区回收
方法区中存放很多常量,在常量(如String a = “abc”)没有引用的时候,会将方法区常量池中的该常量回收。
6. 垃圾收集算法
a. 标记-清除:标记处所有待回收对象并进行统一清除(缺点:效率低、内存碎片多);
b. 复制:内存一分为二,每次回收将存活对象拷贝到另一半中依次存放(缺点:每次只能使用一半内存。新生代中垃圾回收使用该方法。eden80%, from和to各占10%的空间,当10%不够存放80%的eden区域的存活对象时会放入老年代中);
c. 标记-整理:(老年代gc算法)标记所有待回收对象,将存活对象向一端移动,清理掉边界以外的内存;
d. 分代收集:当前商用虚拟机对堆的新生代和老年代采用不同的垃圾收集算法。新生代每次垃圾收集时大量对象需要被清除,采用复制算法进行垃圾清理;老年代中对象存活率高,采用标记-清除或者标记-整理算法进行回收。
7. 垃圾收集器
各收集器详情:垃圾收集器_pp_lan的博客-CSDN博客