Java堆(Java Heap)是JVM所管理的最大内存区域,也是所有线程共享的一块区域,在JVM启动时创建。
此内存区域存放的都是对象的实例和数组。JVM规范中说到:”所有的对象实例以及数组都要在堆上分配”。
Java堆是垃圾回收器管理的主要区域,百分之九十九的垃圾回收发生在Java堆,另外百分之一发生在方法区,因此又称之为”GC堆”。根据JVM规范规定的内容,Java堆可以处于物理上不连续的内存空间中。
当前JVM对于堆的垃圾回收,采用分代收集的策略。根据堆中对象的存活周期将堆内存分为新生代和老年代。在新生代中,每次垃圾回收都有大批对象死去,只有少量存活。而老年代中存放的对象存活率高。
这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。
标记清除算法
标记清除算法是最基础的回收算法,分为标记和清除两个部分:首先标记出所有需要回收的对象,这一过程在可达性分析过程中进行。在标记完之后统一回收所有被标记的对象。
标记清除算法有如下不足
效率问题
标记和清除这两个过程的效率不高
空间问题
清除之后会产生大量不连续的内存碎片,内存碎片太多会导致以后的程序运行中无法分配出较大的内存,从内不得不触发另外的垃圾回收。
如上图中,经过标记清除之后,假设有了100M空间,但是这100M是不连续的,