垃圾收集器与内存分配策略

垃圾收集器与内存分配策略

                      Java语言和C++的不同之处在于内存动态分配和垃圾收集技术

           垃圾收集技术并不是Java语言的伴生产物。早在1960的时候,MIT(麻省理工学院)已经在Lisp语言中真正使用内存动态分配和垃圾收集技术。之所以去了解GC和内存分配,是因为我们需要去排查各种内存溢出和内存泄漏等问题。当垃圾收集成为系统达到更多并发量的瓶颈时,需要对这些技术进行监控和调节。

           程序计数器、虚拟机栈和本地方法栈都是随线程生,随线程灭的;栈中的栈帧随着方法进入和退出进行进栈和出栈。每个栈帧分配多少内存在类结构确定时就已知了(编译期已知)。因此这部分内存的分配和回收存在确定性。因此不需要对这部分多考虑垃圾回收的问题。因为等方法或线程结束,这几个部分就自动回收内存了。而Java堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支所需要的内存也可能不一样,我们只有在运行期间才知道会创建哪些对象,这部分内存的分配和回收是动态的,垃圾收集器所关注的也是这部分内存。

      1 对象已死吗?

      判断一个对象是否需要回收,需要首先判断对象是否存活,对那些死去的对象进行内存回收。

      常用的判断对象是否存活的算法包括引用计数算法可达性分析算法

      1.1 引用计数法

      基本思想:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值减一;任何时刻计数器值为0的对象时就是不可能再被引用的。微软的COM技术、PyThon等都是使用引用计数算法来及逆行内存处理的。但是,主流的Java虚拟机中并未使用该方法来进行内存管理,其中最主要原因时它未解决对象之间循环引用的情况

     例如,objA和objB都存在instance方法,赋值令objA.instance = objB;令objB.instance = objA;除这两个引用关系存在外,再无其他引用。本应对其进行内存回收,但是由于它们互相引用对方,所以引用计数法无法对其进行内存回收。

      1.2 可达性分析算法

      Java,C#等,均采用可达性分析来判断对象是否存活。

      基本思想:将一系列称为“GC Roots”的对象作为起始点,从这些几点开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

  在Java语言中,可作为GC ROOTS的对象包括下面几种:

  虚拟机栈中引用的对象;

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

  方法区中常量引用的对象;

  本地方法栈中JNI引用的对象;

  1.3 再谈引用

  无论是引用计数法还是可达性分析法,都需要使用“引用”。引用可划分为:“强引用”,“软引用”,“弱引用”,“虚引用”。

  强引用就是指在程序代码中普遍存在的,类似“Object obj = new Object()”,只要强引用还在,垃圾回收器永远不会回收被引用的对象

  软引用描述一些还有用但是并非必须的对象,对于软引用关联的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收

  弱引用描述非必需对象

  虚引用是最弱的一种引用,对于是否具有虚引用的存在,对其生存时间没影响

  1.4 生存还是死亡

  即使可达性分析算法中不可达的对象,也必须至少经过两次标记过程来进行判断是否死亡:第一次时,若对象没有与GC roots相关联,判断是否有必要覆盖finalize()方法,如果没有覆盖finalize()方法或者已经执行过finalize()方法,则虚拟机将这两种情况都视为"没有必要执行"。

  任何一个对象的finalize方法都只会被系统自动调用一次,如果对象面临下一次回收,它的finalize()方法不会被再次调用。

  1.5 回收方法区

  在堆中,尤其是新生代中,常规应用进行一次垃圾收集一般可以回收70%-90%的空间,而永久代的垃圾收集效率远低于此

  永久代的垃圾回收主要分为两部分内容:废弃常量和无用的类。

  判断一个常量是否为“废弃常量”很容易,主要看是否有其他地方引用这个常量即可;而判断无用的类,则需要同时满足以下三个条件才可:

  (1) 该类中的所有实例都已经被回收,即Java堆中不存在该类的任何实例

  (2) 加载该类的ClassLoader已经被回收

 

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

 

 

 

 

 

 

 

  

 

 

 

 

 

Elliott Su
原文地址:https://www.cnblogs.com/Elliott-Su-Faith-change-our-life/p/6726866.html