在栈上创建。各种原始数据类型的局部变量,都是在栈上创建的。当程序退出该变量的作用范围
时,这些变量的内存会被释放掉。
在堆中创建,用 new 栈来创建的对象。
堆的空间由垃圾收集器管理,它是一个独立的线程。栈和堆是 JVM 中最重要的两个内存区,JVM 还有
其它的内存区,如方法区、常量池、本地栈等,这些区是不可少的,但同 GC 没什么关系。
第1节、分代复制 GC 收集器
超过 95%的对象的生存期都非常短,分代复制算法根据对象的生存期将对象分为两代。所有的新创建
的对象都在一个类假栈的内存区进行分配,叫做 eden,当这块内存全部分配给对象时,其中大多数已经死
亡了,只要把少数未死亡的长期对象复制到另一块内存中,然后直接更新 eden 的指针就可以了。生命较长
的对象生成的区域叫年老代(old generation)。
分代复制的效率很高,主要的时间花费在复制上。
第2节、标记 GC 收集器
在分代复制 GC 中,说明了 eden 的 GC 收集方式,而在年老代中,通常用标记垃圾收集器,这种垃圾收
集器会从一组根引用开始,遍历所有的对象,如果一个对象被根引用,那么就标记为存活,而存活对象引
用的对象也标记为存活。如此循环,其余死亡的对象就会被回收。
标记垃圾回收器又分为两类:标记紧缩 GC,将所有存活的对象复制到一个连续的区域中,因此可以减
少内存碎片。标记清除 GC,保留所有的存活对象,而将所有死亡的对象的内存空间记录到一个自由空间列
表中,这种方式会产生较多的碎片。
这种收集方式比分代复制方式慢的多,所以只处理年老代。
第3节、增量 GC 收集器
运行标记 GC 时会停止 JVM 中其他程序的线程。造成长时间的停顿。增量 GC 是时间罗长的年老代的 GC
收集分成许多较短的间隔来完成,每次只回收一部分内存。这样用户就不会感觉到停顿。
第4节、次要收集和主要收集
JVM 的内存堆可以分为 4 个部分:permanaent generation, old generation, free space, young
eneration(survivor space*2+eden)。
堆大小由参数-Xms256M, -Xmx512M 控制,如果相等则堆大小不变化。扩展参数 –XX:MinHeapFreeRadio,
指 定 一 个 百 分 比 , 在 GC 后 堆 的 空 闲 空 间 高 于 这 个 百 分 比 , 就 不 扩 展 堆 的 大 小 。
-XX:MinHeapFreeRadio=40。-XX:MaxHeapFreeRadio 正好与之相反。如果高于这个百分比,堆大小就减小。
Permanent generation 保留给 JVM 存放类和方法的反射对象。扩展参数-XX:MaxPermSize,指定大小的
上限-XX:MaxPermSize=64M。