java垃圾回收算法原理

1、堆内存可以分成几块?

2、每块使用什么方法进行垃圾回收?什么时候该回收?

3、内存如何分配以及回收策略?

4、java拥有垃圾回收机制,为什么还会发生内存泄漏?

  

1、堆内存可以分成三块:新生代、老年代和永久代。

2、分代收集算法:标记清除复制标记整理算法

  • 新生代的存活周期比较短,适合使用复制算法。
    • 新生代:eden区域和survive0和survive1(比例是8:1:1),其中eden区域存放刚建立的对象,当eden区域内存用完时会发生GC,存活的对象存入survive0,清空eden区域。当survive0的内存也用完时,继续进行GC,保留eden和survive0区域的存活对象,将其复制survive1区域,清空eden和survive0区域。交换survive0和survive1的角色,一直循环,直到某个survive区域不足以存放另一个survive和eden区域的存活对象时,将这个survive的对象转移到老年代区域。由于新生代对象存活时间短,需要复制的对象少,所以适合使用复制算法,;
    • 老年代:老年代的区域和新生代的区域为2:1。当老年代内存也满了,进行一次全局回收(fullGC)。老年代对象存活率高,使用的回收方法是标记整理算法,标记存活的对象,将其移动到一端(与标记清除算法的区别),回收不存活对象。
    • 永久代:存放静态文件,如静态类和静态方法。但是JDK1.8用元空间取代了永久代。储存在永久代的数据(方法区的数据)一直在转移,转移到堆中。Jdk1.6出现永久代益处,jdk1.7和jdk1.8出现堆溢出

3、内存分配策略

  • 对象优先分配在eden区域;
  • 大对象直接进入老年代;
  • 通过引用计数算法,长期存活对象进入老年代(如对象在新生代中经历15次回收依然存在);

4、场景

  • 使用hashmap、vector等集合类。假设初始化vector,在vector中添加对象,将对象置为null之后,创建的对象仍然不能被回收,因为此时对象有vector引用。
  • 各种资源链接后没有关闭。
  • 监听器的使用

 

你可能感兴趣的:(java)