堆的结构示意图
首先我们需要对jvm虚拟机的堆 有一定的初步了解
在JDK1.8之前设这样的
JDK1.8之后 永久存储区改为元空间 入门的见解
新生区:
- 类: 诞生和成长的地方,甚至死亡;
- 伊甸园: 所有的对象都是在伊甸园区new出来的
- 幸存者区(0,1)
当伊甸园满了(这里假设十个单位)的时候 就会启动轻度gc处理 假如清理了9个单位,剩下一个就进入幸存区0区,
此时幸存区0区:1
当幸存区0区满了的时候 启动重度fullgc处理,活下来的便进入养老区
永久区:
这个其余常驻内存,用来存放jdk自身携带的CLass对象。Interface元数据,存储的是java运行的一些环境或者类信息,这个区域是不存在垃圾回收的。关闭jvm会释放这个区域的内存
- JDK1.6之前:永久代,常量池实在方法区
- JDK1.7:永久代,但是慢慢退化了,区永久代,常量池在队中
- JDK1.8;无永久代,常量池在元空间
关于调优方案1
1 如果栈溢出 (StackOverflowError)我们可以适当调大虚拟机初始化内存和最大内存
2 VM options设置
-Xms8m -Xms8m -XX:+PrintGCDetails
并且控制台打印一些信息
在这里我们可以看到 轻(GC (Allocation Failure))gc回收和重度(Full GC (Allocation Failure) )gc回收
PSYoungGen:新生区
ParOldGen:老年代
新生区+老年代加起来除以(1024*1024)MB 就是最大内存
它这个输出是字节需要转化为mb单位
关于逻辑上的元空间不存在 但是理论上是存在的 因此算出来其实还是会有一些差异的
有一些人给元空间命名为非堆 其实还是在堆里这些都没有错