JVM 对象状态判断01
1 引用计数法
给一个对象添加一个引用计数器,每当有一个地方引用时,计数器加1,当引用失效的时候,计数器减去1.当计数器为0的时候,表示对象不可能再被使用。此时表明该对象可以被回收。
缺点:难以对象之间互相引用。
package com.dusk.service.jvm;
/**
* @Authgor: gosaint
* @Description:
* @Date Created in 22:14 2018/9/10
* @Modified By:
*/
public class RefrenceCountingGC {
public Object instance =null;
private static final int _1MB=1024*1024;
private byte[] bigSize=new byte[2*_1MB];
public static void main(String[] args) {
RefrenceCountingGC refrenceCountingGC1=new RefrenceCountingGC();
RefrenceCountingGC refrenceCountingGC2=new RefrenceCountingGC();
refrenceCountingGC1.instance=refrenceCountingGC2;
refrenceCountingGC2.instance=refrenceCountingGC1;
refrenceCountingGC1=null;
refrenceCountingGC2=null;
System.gc();
}
}
为JVM启动设置参数
-XX:+PrintGCDetails-----------------------------表示详细的GC日志的输出
![](https://images2018.cnblogs.com/blog/1231411/201809/1231411-20180912201608511-1410706937.png)
运行后查看GC日志:
[GC (System.gc()) [PSYoungGen: 6764K->728K(38400K)] 6764K->736K(125952K), 0.0017376 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 728K->0K(38400K)] [ParOldGen: 8K->648K(87552K)] 736K->648K(125952K), [Metaspace: 3422K->3422K(1056768K)], 0.0083313 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 38400K, used 998K [0x00000000d5f80000, 0x00000000d8a00000, 0x0000000100000000)
eden space 33280K, 3% used [0x00000000d5f80000,0x00000000d6079b20,0x00000000d8000000)
from space 5120K, 0% used [0x00000000d8000000,0x00000000d8000000,0x00000000d8500000)
to space 5120K, 0% used [0x00000000d8500000,0x00000000d8500000,0x00000000d8a00000)
ParOldGen total 87552K, used 648K [0x0000000081e00000, 0x0000000087380000, 0x00000000d5f80000)
object space 87552K, 0% used [0x0000000081e00000,0x0000000081ea22b8,0x0000000087380000)
Metaspace used 3437K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 375K, capacity 388K, committed 512K, reserved 1048576K
来吧,分析吧。虽然看不懂但是还要看的。
来看上述的图吧,java堆内存划分为新生代,老年代和永久代,但是在java8取消了永久代,出现了元空间。
Monitor GC:
从Eden到survivor幸存者区域被回收的内存称为 Monotor GC。每次的Monitor GC 都会清除年轻代的内存。
1 当JVM无法为新创建的对象分配内存空间时会触发Monitor GC。
2 当Monitor GC的时候会出现“全世界的停顿”,(stop-the-world),停止应用程序的线程。对于绝大多数程序来说停顿延迟都是可以忽略不计的。
[GC (System.gc()) [PSYoungGen: 6764K->728K(38400K)] 6764K->736K(125952K), 0.0017376 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
1 GC开头的日志[GC和[full GC说明了垃圾这次回收停顿的类型。如果有"Full",表示这次GC发生了“stop-the-world”。这是因为使用System.gc()会触发Full GC. Full GC是情理这个堆空间。
2 [PSYoungGen和[PSYoungGen表示GC发生的区域。分别代表使用Parallel Scavenge(并行收集)和Parallel Old收集新生代和老年代的垃圾回收组合。为什么是这两个垃圾回收的组合呢?因为我自己的JVM默认开启的模式是server.可以通过java -version来看垃圾回收组合。
![](https://images2018.cnblogs.com/blog/1231411/201809/1231411-20180912201722919-630086128.png)
还有一种模式是client模式。默认使用Serial和Serial Old收集器的组合。
3 在方括号中[PSYoungGen: 6764K->728K(38400K)] 后面的”6764K->728K( 38400K)”代表的是”GC前该内存区域已使用的容量->GC后该内存区域已使用的容量(该内存区域总容量)”。GC前使用了6.7M的空间,GC后使用了0.65M的堆空间。该内存的总容量为38.4M。
4 后面的6764K->736K(125952K)表示:GC前该java堆已使用的容量->GC后该java堆已使用的容量(该内存区域总容量)”。GC前java堆使用了6.7M的空间,GC后使用了0.65M的堆空间。该java堆的总容量为125M。
5 0.0017376 secs表示GC所用的时间,单位是秒,卡伊看出是毫秒级别。
6 [Times: user=0.00 sys=0.00, real=0.00 secs] user代表进程在用户态消耗的CPU时间,sys代表代表进程在内核态消耗的CPU时间、real代表程序从开始到结束所用的时钟时间。这个时间包括其他进程使用的时间片和进程阻塞的时间(比如等待 I/O 完成)。
7 当触发Full GC后,可以看出:PSYoungGen: 728K->0K(38400K)] [ParOldGen: 8K->648K(87552K)] 736K->648K(125952K), 新生代从来的728K变为0k,并且新生代内存不变。老年代从8k变化为648k.新生代的对象全部转移到老年代。老年代的内存为87M。java堆内存不变,但是从736k变为648k.因为触发了Full GC。因此回收了整个java堆的垃圾。
这里对元空间暂时不做描述。
当上帝未揭开人类的未来图景之前,人类最伟大的智慧存在于两个词中,“等待”和“希望”