thunisoft成长快乐!Java学习笔记java杂谈

JAVA的内存分配和垃圾收集1:如何判断一个对象是否是存活的

2016-12-11  本文已影响419人  MentallyL

对于jvm的内存分配和GC我想从以下顺序来说:

  1. 如何判断一个对象是否是存活的。
  2. 内存中常用的垃圾回收算法
  3. 常见的垃圾收集器
  4. jvm的内存分配和回收策略

如何判断一个对象是否是存活的

引用计数法:

每当有一个地方引用一个对象的时候计数器就会加1,当引用失效时就会减1。这种看起来是很好的,实现简单,效率也很高。但主流的jvm基本上没有选用这种方式来判断一个对象是否存活的。其主要原因就是它很难解决相互的循环引用。

可达性分析法:

通过“GC Roots”的对象作为起始点,从这些节点开始向下搜索。如果一个对象没有被搜索到(就是说不在这个以Roots根节点的树上),那么则说明对象可以被回收。

示意图

其中可以作为GC ROOTS的对象有以下几种情况:

注:

在这对象被回收时涉及到一个方法,Object对象里的finalize方法。在对象要被回收的时候,会先判断是否当前对象是否重写了finalize()方法,如果重写了则先把这个对象放在一个队列之中。由一个低优先级的Finalizer线程去执行。当在执行finalize()这个方法的时候,如果当前对象重新被已用了,也就是说拯救了自己那么就不会再回收了这个对象。
这个方法不建议大家使用,因为它的不确定性很大,无法保证调用顺序。有些人把这个方法作为“关闭外部资源”的方法,这种用法是错误的,我们完全可以用finally来代替。所以建议大家可以忘掉这个方法的存在。

方法区的回收:

上面说的都是回收在堆中进行的,那方法区中的常量和类的信息会不会被回收呢?答案是可以的。
但对于方法区的回收的效率是比较低的,相比于在年轻带的垃圾回收。

对于一个类的回收是可以通过jvm参数来控制的,具体的参数可以去网上搜索。

在大量使用反射、动态代理、CGlib等框架和OSG这种频繁定义ClassLoader的场景都需要虚拟机应该具有类的卸载功能,以保证永久代中不会溢出。

上一篇下一篇

猜你喜欢

热点阅读