程序计数器、虚拟机栈、本地方法栈随线程而生、随线程而灭

堆和方法区

  一个接口的多个实现类所需的内存不一样,一个方法的多个执行分支所需的内存不一样,在程序执行过程中动态地分配和回收内存

(1)引用计数法

  引用计数器,有一个地方引用,计数器的值加一

  很难解决对象之间循环引用的问题

(2)可达性分析

  GCRoots

  一个对象有没有到GCRoots的引用链

  可作为GCRoots的对象:虚拟机栈中引用的对象

             方法区类静态属性引用的对象

             方法区常量引用的对象

             本地方法栈中JNI(java native interface)引用的对象

 

(1)强引用 垃圾回收器永远不会回收 Object obj = new Object();

(2)软引用 还有用但不必需 在将要发生内存溢出之前,把软引用对象例如回收范围进行二次回收,如果回收之后还没有足够内存,才抛出内存溢出异常

(3)弱引用 非必需对象 弱引用关联的对象只能存活到下一次垃圾回收之前,无论内存是否足够,都回收弱引用管理的对象

(4)虚引用 无法通过虚引用获得对象的实例,设置虚引用,在该对象被垃圾回收之时,收到一个系统通知

 

不可达对象,生存还是死亡?

如果对象在可达性分析之后,没有到GCRoots的引用链------不可达对象

对不可达对象,两次标记过程:

(1)对不可达对象进行第一次标记,检查是否有必要执行finalize()方法

  如果对象没有覆盖finalize方法  或者    该对象的finalize方法已经被虚拟机调用过(任何对象的finalize方法只会被调用一次)     认为没有必要执行finalize方法

  如果有必要执行finalize方法

  将对象放在F-Queue队列中,并稍后由一个虚拟机建立的、低优先级的Finalizer线程执行它(Finalizer线程会触发finalize方法,但不一定会等待该方法执行完毕)

(2)对F-Queue队列中的对象进行第二次标记,检查是否在finalize方法中自救成功

  如何自救?将自己重新与引用链上的任何一个对象建立关联

  如果自救成功

  该对象将被移出即将回收的集合

 

判断一个类是否是无用的类?

(1)java堆中不存在该类的任何实例

(2)该类的classloader已经被回收

(3)该类对应的java.lang.Class类的实例没有在任何地方被引用,无法在任何地方通过反射访问类的成员

 

垃圾回收算法

(1)标记-清除

  内存碎片效率低

(2)复制

  无内存碎片

  浪费部分内存空间

  新生代  采用复制算法回收:Eden: Survivor:Survivor = 8:1:1(10%的空间浪费)

(3)标记-整理

  没有内存碎片

(4)分代收集

  新生代:复制

  老年代:标记-整理  标记-清除