HotSpot和堆
一:我们学的JVM虚拟机版本为HotSpot虚拟机sun公司的
二:堆(Heap)
一个JVM只有一个堆内存,堆内存的大小是可以调节的。
类加载器读取了类文件后,一般会把什么东西放在堆中? 类,方法,常量,变量,保存我们所有引用类型的真实对象。(栈中一般都是引用)
堆内存中还要细分三个区域:
新生代(伊甸园(Eden Space),幸存区(1),幸存区(2))
当我们new对象的,在第15次轻量垃圾回收后,依然幸存后就放入到幸存区中,当经过20次后进入到养老区,当养老代也满了,我们就进行重量级垃圾回收。
新生代:类:诞生和成长的地方,甚至死亡的地方。
对象都是在伊甸园区new出来的,比如我们伊甸园区只能容纳10个对象,当满10个对象我们就要进行垃圾回收,有的对象活下来了,有的死了,比如有1个活下来就放在幸存区,那么剩下的都死了。这时候伊甸园又有10个位置。
当我们的幸存区满了,我们就要触发一下重GC,重GC结束后那么我们把存活的放入到永久代,这个时候,养老代又有空间了。
真理:经过研究,99%的对象都是临时对象。
养老代()
永久代():
这个区域常驻内存的,用来存放jdk自身携带的Clsss对象,interface元数据,存储java运行时的一些环境。
一个启动类,加载了大量的第三方jar包,Tomcat部署了太多的应用,大量动态生成的反射类,不断的被加载。知道内存满,就会出现oom;
这个区域不存在垃圾回收,关闭虚拟机会释放这个区域的内存。
jdk1.6:永久代,常量池在方法区中
jdk 1.7:永久代,但是慢慢退化了,去永久代,常量池在堆中
jdk1.8 :无永久代,常量池在元空间;方法区也在元空间里面;
方法区是非堆:存放永久的比如接口,java的第三方jar包等等。
(元空间里面有方法区,方法区里面有一小部分是常量池):底下就是1.8的现状
GC垃圾回收主要在伊甸园区和养老代。
假设内存满了,叫OOM,堆内存不够。
在jdk8以后,永久代叫元空间