提示

1.自动进行垃圾回收,这里的垃圾,是指内存中不在使用,进行自动释放的过程
2.垃圾回收,主要针对的是java中的堆。因为虚拟机栈,是进行出栈,入栈操作。一般直接就释放了。 程序计数器就一个指针,无需释放。本地方法栈,需要人工释放(我的理解,不确定)? 元数据区,是需要进行垃圾回收的。方法区主要回收废弃变量和废弃类。
3. 垃圾收集器垃圾回收算法

:: 我的理解

针对垃圾回收,最主要的就是定义什么是垃圾?
如果判断是垃圾?引用计数法可达性分析.不管是引用还是引用链,都和引用 有关,根据可收回的程度,来区分引用类型。
在判断了垃圾之后,就涉及到如果进行回收的问题。主要的步骤可以想到是,标记哪些是垃圾,然后进行清除。这就涉及到了垃圾回收算法
垃圾回收,还有个finalize方法,这里不做引申。可能在finalize方法内复活等奇怪操作。

[引用计数法]

优点: 简单,效率高,回收延迟低
缺点: 无效的数据,循环引用无法判断。
1个方法,都是有一定的适用背景的,如java没采用并不一定不好。python回收垃圾,采用的就是引用计数法。那python如何解决循环引用呢?

  1. 人工解除
  2. 使用弱引用,weakref,python提供的标准库,旨在解决循环引用

可达性分析 — 引用链

技巧💡

GC Roots 并不包括堆中对象所引用的对象,这样就不会有循环引用的问题。

思路: 找一些root节点,去遍历这个root节点下的子节点,如果没遍历到,即这个对象是孤立节点,或者有一些循环引用的节点是孤立的。这些就算是垃圾。
这个是难点在于确认,哪些能作为root节点,而避免有用数据被垃圾回收。

root节点有:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 本地方法栈(Native 方法)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 所有被同步锁持有的对象

垃圾回收时机?

被标记成了可回收,不一定马上被回收。

引用

技巧💡

不管是引用计数法,还是可达性分析(引用链),都需要根据引用类型来判断是否有这个引用。

引用类型

为什么引用需要区分类型?

希望能描述这一类对象:当内存空间还足够时,则保留在内存中;如果内存空间在进行垃圾收集后还是非常紧张,则可以抛弃这些对象。很多系统的缓存功能都符合这样的应用场景
强引用(不可回收) >> 软引用 (如内存,gc后内存不够回收)>> 弱引用(只要GC,就回收,不管内存够不够) >> 虚引用(无法获取真实引对象,主要用于gc回收后的触发机制)

强引用,存在就不会被回收
软引用,典型场景,内存,JVM不足时,才去回收
弱引用, 当 JVM 进行垃圾回收时,无论内存是否充足,都会回收只被弱引用关联的对象。
虚引用, 最弱的引用,主要是用来保证对象被finalize后,执行某个事情。