堆 heap
一个JVM只有一个堆内存,堆内存的大小是可以调节的。
类加载器读取了类文件后,一般会把什么东西放到堆中?
类、方法、常量、变量,保存我们引用类型的真实对象
堆内存中还要细分未三个区域:
- 新生区(伊甸园区【eden space】) young/new
- 养老去 old
- 永久区 perm
新生区还可以细分为三个区
- 伊甸园区
- 幸存0区
- 幸存1区
一个对象 经历了GC后没有被回收 将进入幸存区。
幸存区其中一个满了会和另一个幸存区互换位置 也就是 from 和to
达到一定次数GC [轻GC] 回收还存在的对象将进入老年区 【重GC full GC】
GC 垃圾回收主要是在 伊甸园区 和养老区
内存满了一般出现 OOM, 堆内存不够。
在JDK8之后,永久存储区 更名为 元空间
新生区
- 类:诞生 和成长的地方,甚至死亡
- 伊甸园区,所有的对象都是从伊甸园区 new 出来的
- 幸存者区(1、0)
伊甸园区满了 会触发 轻GC ,幸存下来的 进入 幸存区 。
幸存区 和伊甸园区都满了 触发 重GC 把 二者【幸存区和伊甸园区】都清一下,幸存下来的进入养老区。
经过研究,99%的对象都是临时对象!正常进入养老区比较少,很少看到OOM
永久区
这个取羽常驻内存的,用来存放jdk自身携带的Class对象。Interface 元数据,存储的是java运行时的一些环境或类信息。
此区域不存在垃圾回收! 关闭 JVM 虚拟机就会释放这个区域的内存。
一个启动类加载了大量的第三方Jar。或者tomcat 部署了太多应用。或者大量动态生成的反射类,不断的被加载。直到内存满,就会出现OOM
- jdk 1.6前: 永久代,常量池是在方法区
- jdk1.7:永久代,但是慢慢退化了,推出 去永久代 概念,常量池在堆中
- jdk1.8之后: 无永久代,常量池在元空间
元空间(meta space): 逻辑上存在 物理上不存在
-Xms1024m -Xmx1024m -XX:+PrintGCDetails
新生代物理磁盘空间+老年代物理磁盘空间 = 堆内存
故:元空间也称为 非堆
+PrintGCDetails
新生代物理磁盘空间+老年代物理磁盘空间 = 堆内存
故:元空间也称为 非堆