Java垃圾回收机制
文章目录
引言
“两者之间存在一堵由内存分配与GC技术筑建起来的高墙,墙里面的人想出去,墙外面的人却想进来”。
理解GC机制,必须要对JAVA内存区域很熟悉,如果不熟悉JAVA内存区域,建议先看上一篇文章《Java内存区域》
GC概念
- GC的区域
- GC的对象
- GC的时机
- GC算法
- GC执行器
GC的区域
JVM中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于 java 堆和方法区中,在程序运行期间,这部分内存的分配和使用都是动态的。
GC分析算法
- 引用计数算法
- 该算法已经废弃,如果两个垃圾对象互相引用,将发生内存泄漏。
- 可达性分析
- 从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。不可达对象。
在Java语言中,GC Roots包括:
虚拟机栈帧中引用的对象(方法内部引用外部的对象)。
方法区中类静态属性实体引用的对象(依赖)。
方法区中常量引用的对象(对象的属性依赖)。
本地方法栈中JNI引用的对象。
再谈引用
JDK1.2之后,为了方便进行可达性判断与提高GC性能,对引用进行分类。
引用类型 | 回收时机 | sample |
---|---|---|
强引用 | 只要强引用还在,就永远不会回收 | A a=new A(); |
软引用 | 如果引用不在,立即回收,否则,在发生OOM之前,对软引用对象进行回收,SorfReference实现软引用 | … |
弱引用 | 下一次GC之前将被回收(ThreadLocal的内存泄漏问题,K是软引,而V不是,如果线程是线程池,那么线程不回收,就存在一条对V的强引用通路,会导致内存泄漏,因此要手动调用remove) | WeakReference |
虚引用 | 无法通过虚引用来调用对象,唯一的用处就是在GC时能收到系统的通知 | PhantomReference |
堆内存回收
//通过-XX:PrintGCDetails
Heap
PSYoungGen total 59392K, used 14950K [0x0000000780700000, 0x0000000784700000, 0x00000007c0000000)
eden space 53248K, 28% used [0x0000000780700000,0x0000000781599b48,0x0000000783b00000)
from space 6144K, 0% used [0x0000000783b00000,0x0000000783b00000,0x0000000784100000)
to space 6144K, 0% used [0x0000000784100000,0x0000000784100000,0x0000000784700000