一、JVM体系结构
二、JVM Heap Memory1.新生代(Young Generation)
- Eden Space
- Survivor FromSpace (S1)
- Survivor ToSpace (S2)
备注:Young Generation中的98%的对象都是死朝生夕死,所以将内存分为一块较大的Eden和两块较小的Survivor1、Survivor2,JVM默认分配是8:1:1。
2.老年代(Old Generation)
- Tenured
3.永久代(Permanent Generation)
- 包含类、方法等细节的元信息
- 在Java8中已被移除
三、垃圾回收过程新生代GC(Minor GC):
1.一个新创建的对象,首先会被存储在新生代的Eden 中,Eden空间不足时,GC,将存活的对象(仍然被引用的)从 Eden 移动到 Survivor1;
2.Survivor1空间不足时,GC,将Eden和Survivor1中存活的对象,移动到Survivor2,如果Survivor2空间不足,则全部移动到老年代;
3.Survivor2空间不足时,GC,将Eden和Survivor1中存活的对象,移动到Survivor1,如果Survivor1空间不足,则全部移动到老年代;
老年代GC(Major GC / Full GC):
垃圾回收算法:Mark-Compact
相对于 Java 垃圾回收过程,老年代是对象生命周期的最后阶段。Major GC 扫描老年代的垃圾回收过程。如果实例不再被引用,那么它们会被标记为回收,否则它们会继续留在老年代中。
四、垃圾回收算法①Mark-Sweep(标记-清除)算法
这是最基础的垃圾回收算法,之所以说它是最基础的是因为它最容易实现,思想也是最简单的。标记-清除算法分为两个阶段:标记阶段和清除阶段。标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占用的空间。具体过程如下图所示:
从图中可以很容易看出标记-清除算法实现起来比较容易,但是有一个比较严重的问题就是容易产生内存碎片,碎片太多可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间而提前触发新的一次垃圾收集动作。
②Copying(复制)算法
为了解决Mark-Sweep算法的缺陷,Copying算法就被提了出来。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,这样一来就不容易出现内存碎片的问题。具体过程如下图所示:
这种算法虽然实现简单,运行高效且不容易产生内存碎片,但是却对内存空间的使用做出了高昂的代价,因为能够使用的内存缩减到原来的一半。 很显然,Copying算法的效率跟存活对象的数目多少有很大的关系,如果存活对象很多,那么Copying算法的效率将会大大降低。我们的新生代GC算法采用的是这种算法
③Mark-Compact(标记-整理)算法
为了解决Copying算法的缺陷,充分利用内存空间,提出了Mark-Compact算法。该算法标记阶段和Mark-Sweep一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存。具体过程如下图所示:
在一般厂商JVM中老年代GC就是使用的这种算法,由于老年代的特点是每次回收都只回收少量对象。
五、垃圾回收器1.串行垃圾回收器(Serial Garbage Collector)
串行垃圾回收器通过持有应用程序所有的线程进行工作。它为单线程环境设计,只使用一个单独的线程进行垃圾回收,通过冻结所有应用程序线程进行工作,所以可能不适合服务器环境。它最适合的是简单的命令行程序。
2.并行垃圾回收器(Parallel Garbage Collector)