参考:
内存模型:https://blog.csdn.net/qq_34280276/article/details/52783096
类加载原理:https://nomico271.github.io/2017/07/07/JVM%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/
垃圾回收机制:http://www.importnew.com/26821.html,https://blog.51cto.com/chenhai/1051926
垃圾回收机制:
虚拟机调优:
一、JVM内存模型
堆内存:保存所有引用数据类型的真实信息
方法区:属于共享区域,所有的方法信息都定义在该区
栈内存:基本类型、运算、指向推内存的指针,与线程拥有相同的生命周期
程序计数器:是一个非常小的内存空间,用于指向下一个要执行的代码
本地方法栈:调用本地方法的接口
二、类加载原理
JVM类加载过程分为:加载、验证、准备、解析、初始化、使用、卸载
加载:将.class 文件中的二进制字节流读入到JVM,完整的步骤包括
1.通过类的全限定名获取类的二进制字节流
2.将字节流代表的静态存储结构转化为方法区的运行时数据结构
3.在内存中生成一个改类的 Class 对象
验证:主要确保加载进来的字节流符合JVM规范。
1.文件格式验证
2.元数据验证
3.字节码验证
4.符号引用验证
准备: 静态变量在方法区分配内存,并设置默认初始值
解析:虚拟机将常量池内的符号引用替换为直接引用的过程
初始化:初始化是类加载的最后一步,主要根据程序中的赋值语句为类变量赋值
1.先初始化父类,再初始化子类
初始化条件:
1.使用new
2.设置类静态字段
3.调用静态方法
4.使用反射,对类反射调用
类加载器:
类加载器:
启动类加载器:Bootstrap ClassLoader 负责加载Java_HOME/lib ,或者通过-Xbootclasspath 指定路径,且被认可的类
扩展类加载器:Extension ClassLoader :加载JAVA_HOME\LIB\ext 目录中,或者通过java.ext.dirs 系统变量指定路径的类库
应用程序类加载器:Application ClassLoader:也称作系统类加载器,负责加载用户路径 classpath 上的类库
自定义类加载器:
类加载器之间的模型叫做:双亲委派模式
该模型,除了顶层的类加载外,其余的类加载器都应该有自己的父类加载器,父子关系通过组合实现。
双亲委派工作过程:
如果一个类接收加载请求,自己不会加载这个请求,而是将这个类加载请求委派给父类加载器,直到顶层,当父类无法加载时,子类才会尝试加载
三、JVM 垃圾回收机制
垃圾回收机制:GC,垃圾收集机制指将那些不再使用的对象占用的空间释放。
GC 原理:
Java 内存的管理实际上是对对象的管理,包括对象的分配与释放。
如何确定一个对象是否可以被回收?
常用的算法:引用计数算法、可达性分析算法
引用计数算法的缺点明显,一般都采用的是可达性分析
判断是否可达的GC root:
1.虚拟机栈中引用的对象
2.方法区中静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中引用的对象
当确定了可以回收的对象后,如何对对象回收?
1.标记-清除
标记需要清除的对象,清除带有标记的对象,容易造成内存碎片化
2.标记-整理
是标记-清除的高级版,删除标记的对象,对剩余的对象进行整理,不会产生碎片
3.复制
将内存分为2快,再一块满后将活在的对象复制到另一半,清除前面的一般内存。造成内存可用缩小一半
4.分代收集算法
将内存分为新生代、老年代,对不同的区域使用不用的算法
新生带存活的对象较多,采用复制算法
老年代存活对象较少,使用标记-清理 or 标记 -整理