一、JVM结构
JVM区域总体分两类,heap区和非heap区。

heap区分为:

Eden Space(伊甸园)、
Survivor Space(幸存者区)、
Old Gen(老年代)。

非heap区分:

Code Cache(代码缓存区);
Perm Gen(永久代);
Jvm Stack(java虚拟机栈);
Local Method Statck(本地方法栈);

Permanent Sapce即 持久代(Permanent Generation)

主要存放的是Java类定义信息,一般不用配置,与垃圾收集器要收集的Java对象关系不大。

Heap Space= { Old + NEW = {Eden, from, to} },Old 即 年老代(Old Generation),New 即 年轻代(Young Generation)。年老代和年轻代的划分对垃圾收集影响比较大,Heap大小可以通过-X参数来设定。

二、PermanentSapce
永久区参数设置
JDK8之前可设置永久区大小

参数设置示例: -XX:PermSize=5M -XX:MaxPermSize=7M

JDK8中已经完全移除了永久带。PermSize和MaxPermSize参数也一并移除了。JDK 8中使用MetaSpace来替代。

-XX:MetaspaceSize=<NNN> <NNN>是分配给类元数据区(以字节计)的初始大小(初始高水位),超过会导致垃圾收集器卸载类。这个数量是一个估计值。当第一次到达高水位的时候,下一个高水位是由垃圾收集器来管理的。
-XX:MaxMetaspaceSize=<NNN> <NNN>是分配给类元数据区的最大值(以字节计)。这个参数可以用来限制分配给类元数据区的大小。这个值也是个估计值。默认无上限。
-XX:MinMetaspaceFreeRatio=<NNN>,<NNN>是一次GC以后,为了避免增加元数据区(高水位)的大小,空闲的类元数据区的容量的最小比例,不够就会导致垃圾回收。
-XX:MaxMetaspaceFreeRatio=<NNN>,<NNN>是一次GC以后,为了避免减少元数据区(高水位)的大小,空闲的类元数据区的容量的最大比例,超过就会导致垃圾回收。

JVM MetaSpace参数设置:
设置MetaspaceSize 起始是设置MetaspaceSize 空间触发GC的阈值,而不是设置初始分配空间。

-XX:MetaspaceSize=256m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\oom.dump

二、Heap Sapce

新生代

new{=Eden,from,to}

新生代(Young generation)的空间太小,导致有一些本应该可以很快就被回收的对象被放到了老生代(Old generation)里,导致老生代上涨很快,频繁Full GC。

新生代应该大约占JVM内存的1/3。

Eden Space 伊甸园区

对象被创建的时候首先放到这个区域,进行垃圾回收后,不能被回收的对象被放入到空的survivor区域。

Survivor Space幸存者区
Survivor有两个,分别为To Survivor、 From Survivor。

Survivor Space 用于保存在eden space内存区域中经过垃圾回收后没有被回收的对象。
From/To Survivor 执行垃圾回收的时候Eden区域不能被回收的对象被放入到空的survivor。
To Survivor 和 From Survivor的标记会互换,始终保证一个survivor是空的。

新生代中执行的垃圾回收被称之为Minor GC(因为是对新生代进行垃圾回收,所以又被称为Young GC),每一次Young GC后留下来的对象age加1。

Old Gen老年代

用于存放新生代中经过多次垃圾回收仍然存活的对象,也有可能是新生代分配不了内存的大对象会直接进入老年代。经过多次垃圾回收都没有被回收的对象,这些对象的年代已经足够old了,就会放入到老年代。

当老年代被放满的之后,虚拟机会进行垃圾回收,称之为Major GC。由于Major GC除并发GC外均需对整个堆进行扫描和回收,因此又称为Full GC。

堆外内存
是把内存对象分配在Java虚拟机的堆以外的内存,包括JVM自身运行过程中分配的内存,JNI 里分配的内存、java.nio.DirectByteBuffer 分配的内存等,这些内存直接受操作系统管理。这样能一定程度的减少GC对应用程序的影响。但 JVM 不直接管理这些堆外内存,存在 OOM 的风险,可以在 JVM 启动参数加上 -XX:MaxDirectMemorySize,对申请的堆外内存大小进行限制。

三、GC
查询JVM用了什么GC。

java -XX:+PrintCommandLineFlags -version