ps:本人的一点浅薄理解,如有错误的地方,望大佬指点 ^^~~
.java文件从编译到运行流程图解
运行时数据区(JVM)
运行时数据区分为两部分:线程共享区,线程独占区
线程共享区:方法区(元空间)、栈
线程独占区:java栈、本地方法栈、程序计数器
详细介绍:
方法区(元空间):
1. Class文件信息(编译时诞生):编译完成后,这时候会将所有Class文件信息中的所有字面量和符号引用存入里面的常量池中
ps:如果定义的字段没有被其它地方引用,不会被编译器放入常量池中!!!!!
2. 运行时常量池(程序运行时诞生):程序运行时,在类加载阶段 加载常量池中所有信息,如果常量池中存在对应的符号引用的数据 则会将 符号引用 变为 直接引用
ps:
符号引用:符号引用以一组符号来描述引用的目标,与虚拟机实现的内存布局无关,引用的目标并不一定已经加载在内存中。这里可以将 符号引用 理解为 真实地址的一个占位符~。
直接引用:直接引用是直接指向目标的指针、目标的具体地址,引用的目标一定已经加载在内存中,也就是目标一定是真实存在内存当中的
堆:
1.存储类、方法、常量、变量、字符串常量池、被引用的真实对象
ps:在首次使用某个字符串字面量时,字符串字面量以真正的String对象的方式存放在 字符串常量池中
JAVA栈:
在编译程序代码的时候,栈帧中需要多大的局部变量表,多深的操作数栈都已经完全确定了。
因此一个栈帧需要分配多少内存,不会受到程序运行期变量数据的影响,而仅仅取决于具体的虚拟机实现
- 存储对象的引用、八大基本数据类型
- 每个线程都有一个栈,一个栈由无数个栈帧构成,这是线程安全,不同线程的栈帧不能互相引用
- 栈帧的排序是从下往上以此递增,遵守 先进后出,后进先出原则。最顶层的栈帧叫 当前栈帧,只有 当前栈帧才是有效的,与这个栈帧相关联的方法称为 当前方法。每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在JVM里面从入栈到出栈的过程
4. 一个栈帧由 局部变量表 操作数栈 动态连接 返回地址组成
本地方法栈:主要操作 用native修饰的方法 去调用的 .dll 、.so 的文件里的方法
程序计数器:如果线程正在执行的是一个 Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行的是 Native 方法,这个计数器值则为空(Undefined)
垃圾回收(GC):
新生代:
伊甸园区:所有对象都是在伊甸园区被new出来的
幸存者0、1区(to、from):这两个区域是互相交换的,谁是空的 谁就是 to,不为空的就是 from
老年代:从新生代幸存来的对象
元空间:
这个区域是常驻内存。用来存放JDK自带的Class对象、interface元数据,存储的是Java运行时的一些环境或类信息~,这个区域不存在垃圾回收!关闭虚拟机就会释放这个区域的内存~
一个启动类,加载了大量的第三方jar包,tomcat部署了太多应用,大量动态生成的反射类,不断的被加载,直到内存满,就会出现OOM
垃圾回收流程:
对象都是在伊甸园区,当伊甸园区满了之后,进行一次 MinorGC (轻GC) ,判断对象是否存活(可达性分析算法),如果对象存活 则进入 幸存者区(这里使用的是 复制算法),当对象经历了15次MinorGC还存在的话 就会从幸存者区进入老年代(这里使用的是标记清除算法+标记压缩算法),当老年代满了之后 会进行一次 MajorGC/FullGC(重GC)
MinorGC (轻GC) :
触发条件:Eden区满时,触发
MajorGC/FullGC(重GC):
触发条件:System.gc()方法的调用
老年代空间不足
方法区空间不足
通过Minor GC后进入老年代的平均大小大于老年代的可用内存
由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小
复制算法:
好处:没有内存碎片
坏处:浪费了一半存储空间。多了一半空间永远是 to(极端条件下)
标记清除算法:
好处:没有浪费额外的内存空间
坏处:扫描了两次,消耗时间过长,会出现内存碎片
标记压缩算法:
好处:没有浪费额外的内存空间,不存在内存碎片
坏处:扫描了三次,消耗时间过长
标记清除压缩算法:
好处:节约了一部分时间
内存效率(时间利用率):复制算法 > 标记清除算法 > 标记整理算法
内存整齐度:复制算法 = 标记压缩算法 > 标记清除算法
内存利用率:标记压缩算法 > 标记清除算法 > 复制算法
根据这些算法的优缺点得出结论:
使用分代收集算法是最优的(新生代使用 复制算法,老年代使用 标记清除算法+标记压缩算法 混合使用)
新生代:对象存活率低,所以使用 复制算法
老年代:区域大,存活率高 。所以 标记清除算法+标记压缩算法 混合使用