JVM内存机构
- 虚拟机栈
- 本地方法栈
- 程序计数器
- 堆
- 方法区
其中程序计数器、虚拟机栈和本地方法栈3个区域随线程启动与销毁, 因此这几个区域的内存分配和回收都具有确定性,不需要过多考虑回收的问题。而Java堆区和方法区则不一样,这部分内存的分配和回收是动态的,正是垃圾回收需要关注的部分。
如何确定垃圾是否可回收的两种算法
- 引用计数算法
- 可达性算法
引用计数算法
给对象添加一个引用计数器,每当有一个地方引用它时,计数器值+1,每当一个引用失效时,计数器-1.当对象的计数器为0的时候,就表示对象是没有在被引用的了
优点:实现简单,判定效率高
缺点:如果出现A对象引用B对象,B对象引用A对象的循环引用情况,会导计数器永远不为0
可达性算法
通过一个叫"GC Root根"的对象引用作为起点,一直往下进行搜索引用,所走过的路称为引用链,当一个对象GC Root根是没有任何引用到它的时候,则证明这个对象是废弃的,也就是可以回收的。这就是可达性分析算法。
哪些对象可以充当GC ROOT根对象?
- 虚拟机栈中的引用对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中引用的对象