jvm运行时数据区:
数据共享:
堆、方法区(运行时常量池StrngTable)、
数据私有:
栈、本地方法栈、程序计数器
常量池:
编译时将数据(类名、方法名、参数类型、字面量)写入字节码文件中,就是一张表。
运行时常量池:
把常量池放入内存中,并把里面的符号(#1、#2)变为真实地址。运行时常量池一直都是在方法区(JDK1.8 实现为元空间)中。字符串常量池由方法区 到 堆 到 元空间。
GC :
判断垃圾方法:
1、引用计数法,会造成内存泄漏问题(对象的引用计数永不为0)
2、可达性分析,是否被根对象所引用
4种引用:
强:new
软:垃圾回收时,内存不够就释放
弱:垃圾回收时,直接释放
虚:不会
垃圾回收算法:
标记清除:速度快,会有内存碎片
标记整理:速度慢,没有内存碎片
复制:双倍内存空间
分代:
新生代
伊甸园:新创建的对象放在伊甸园中,当伊甸园第一次放不下的时候,会判断哪些是垃圾,并采用Minor GC (复制算法)(Stop the world),将存活下来的对象放入幸存区 To中,并交换幸存区From与To的位置,幸存区中的对象寿命加1。
当伊甸园第二次放不下的时候,不仅要判断伊甸园的垃圾,还要判断幸存区的垃圾,并进行Minor GC
。。。。。。
老年代
当幸存区的对象寿命超过一个阈值(最大为15)时,就可以将对象由新生代转到老年代中,当新生代和老年代都放不下时,会先触发Minor GC ,在触发Full GC (Stop the world),如果还是放不下,就会出现内存溢出的错误。
类加载器:
加载:
1、将类的字节码文件载入方法区(JDK1.8实现为元空间)
2、如果这个类还没有加载父类,先加载父类
3、加载和链接可能是交替运行的
链接:
验证:魔数
准备:为static变量分配空间,并设置默认值,JKD1.8静态变量存储在堆中,早期存储在方法区中。
分配空间在准备阶段,赋值在初始化阶段,
被final修饰的基本类型,赋值在准备阶段,
被final修饰的引用类型,赋值在初始化阶段。
解析:将常量池中的符号引用解析为直接引用
初始化: