文章目录
三种JVM
-
Sun公司,HotSpot(常用)
-
Oracle,JRockit
-
IBM,J9VM
堆
- ==Heap,一个JVM只有一个堆内存,堆内存的大小是可以调节的。==而栈是线程级别的。
类加载器读取类文件够,一般会把什么东西放在堆中呢?
- 类的具体实例,方法,常量,保存所有引用类型的真实对象。
堆内存细分为三个区域
新生区(伊甸园区)young
- 类:诞生,成长甚至死亡的地方。(活的足够长的类,可能会进入老年区,但是大部分在新生区就玩完了。)
- 伊甸园区,所有的对象一开始都是在伊甸园区new出来的。
- 幸存者区(0,1)
老年区,old
- 新生区的对象满了,就放入老年区。
统计上:绝大部分的对象都是临时对象,很少有对象能活到老年区。
永久区,perm->元空间
这个区域是常驻内存的,用来存放JDK自身携带的Class对象,Interface原数据。简单理解为java运行时的环境或类信息。这个区域不存在垃圾回收!关闭JVM虚拟机就会释放这个区域的内存。
元空间:逻辑上存在,物理上不存在,这也是将其称为“非堆的原因”!
这个区域的空间会不会被占满呢?可以的。比如
- 一个启动类,加载大量的第三方的jar包
- tomcat部署了太多的应用
- 大量动态生成的反射类
关于永久区的变化
-
jdk1.6之前:永久代,常量池在方法区中
-
jdk1.7:去永久代,常量池在堆中
-
jdk1.8,:无永久代,常量池在元空间
其他
- GC 垃圾回收,主要是在伊甸园区和老年区
- 内存爆满,会产生OOM(OutOfMemoryError)错误。
- JDK8以后,永久存储区的名字变为元空间。
调整JVM的内存空间大小
OOM问题的可能解决办法
-
尝试扩大内存,看结果
-Xms1024m -Xmx1024m -XX:+PrintGCDetails
-
分析内存,查看问题,借助JProfiler
参考自狂神说