JVM 总结

1.JVM、JRE、JDK的关系
在这里插入图片描述
2.JVM类加载-初始化过程

  • loading 加载
  • linking 校验: 验证文件是否符合JVM规定 准备: 给静态变量赋默认值 解析: 将类、方法、属性等符号引用解析为直接引用 常量池中的各种符号引用解析为指 针、偏移量等内存地址的直接引用
  • initializing 初始化 调用类初始化代码 ,给静态成员变量赋初始值

3.双亲委派机制原理?

  • 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行
  • 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达项层的启动类加载器
  • 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载

4.为什么要采用双亲委派机制?
1)避免核心API被篡改
2)避免类的重复加载

5.如何自定义类加载器?
1)自己写一个类加载器
2)重写findclass方法

6.如何打破双亲委派机制?
1)自己写一个类加载器
2)重写loadclass方法(重点)
3)重写findclass方法

7.讲述JMM(java内存模型)

  • 是一个抽象的概念,是一种虚拟机规范,主要目标是定义程序中各个变量的访问规则。屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各平台下都能够达到一致的内存访问效果。
  • 所有的变量都存储在主内存中,每个线程还有自己的工作内存,工作内存存储在高速缓存或者寄存器中,保存了该线程使用的变量的主内存副本拷贝。
  • 工作内存是JMM的一个抽象概念,并不真实存在,它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。
  • 线程只能直接操作工作内存中的变量,不同线程之间的变量值传递需要通过主内存来完成。

8.volatile有两个语义?
1)volatile可以保证线程间变量的可见性。
2)volatile禁止CPU进行指令重排序。

9.JVM运行时数据区组成

线程共享区:
1.堆
2.方法区(Method Area):存储已被jvm加载的类信息、常量、静态变量、编译器编译的代码(字节码)等数据
线程特有区:
1.java 虚拟机栈 (1个方法对应一个栈帧)
栈的结构是栈帧组成的,调用一个方法就压入一帧,帧上面存储局部变量表,操作数栈,动态链接 ,方法出口信息,局部变量表存放的是 8 大基础类型加上一个引用类型
2.本地方法栈 :主要为native方法服务
3.程序计数器:记录当前线程执行的行号

10.方法区和永久代(1.8之前)的区分
方法区是Java虚拟机规范中的定义,是一种规范,而永久代是一种实现

11.永久代(jdk<1.8)和元空间(jdk>1.8)

  • 永久代:用于存放类和方法的元数据以及常量池 可调节大小(-XX:PermSize、-XX:MaxPermSize)。物理上是堆的一部分,和新生代、老年代地址是连续的。
  • 元空间:本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,-XX:MaxMetaspaceSize 参数来指定 Metaspace 区域的大小。

12.举个内存泄漏例子
一个类中定义了全局变量,但是只在一个方法里面使用并初始化了。而且没有在该方法最后置空。这样这个全局变量只能在该类生命周期结束时才能被回收。

public class Simple {
    Object object;
    public void method1(){
        object = new Object();
        //...其他代码
    }

13.GC如何定位垃圾?
1)引用计数法
2)根可达算法
可以作为GC Roots的对象包括下面几种:
虚拟机栈(栈帧中的本地变量表)中引用的对象;
方法区中类静态属性引用的对象;
方法区中的常量引用的对象;
本地方法栈中JNI(即一般说的Native方法)的引用的对象;

14.垃圾回收算法?
1)标记清除
这种算法分两步:标记、清除两个阶段,标记阶段是从根集合(GC Root)开始扫描,每到达一个对象就会标记该对象为存活状态,清除阶段在扫描完成之后将没有标记的对象给清除掉。适合存活对象较多的情形。
2)复制
将可用内存按容量分为大小相等的两块,每次都只使用其中一块,不会产生碎片,适合存活对象较少的情形
3)标记整理(标记压缩)
也是从根集合(GC Root)开始扫描进行标记然后清除无用的对象,清除完成后它会整理内存。所以不会产生碎片,但是效率偏低(两遍扫描,指针需要调整)
JVM回收算法小结:
标记清除速度快,但是会产生内存碎片
标记整理解决了标记清除内存碎片的问题,但是每次都得移动对象,因此成本很高
复制算法没有内存碎片也不需要移动对象,但是导致空间的浪费

15.JVM什么时候对象会进入老年代?
1)经历的YGC次数达到了阀值(默认15,可通过参数调节)还存活。
2)大对象直接进入老年代
如果设置了-XX:PretenureSizeThreshold这个参数,那么如果你要创建的对象大于这个参数的值,比如分配一个超大的字节数组,此时就直接把这个大对象放入到老年代,不会经过新生代。
3)动态年龄
根据对象年龄有另外一个策略也会让对象进入老年代,不用等待15次GC之后进入老年代,他的大致规则就是,假如当前放对象的Survivor,某个年龄的对象的总大小大于这块Survivor内存的50%,那么大于这批对象年龄的对象,就可以直接进入老年代了。

16.GC触发条件
YGC(Minor GC):eden区满了
Full GC
1)老年代空间不足
2)方法区空间不足
3)通过YGC后进入老年代的平均大小 大于 老年代当前可用大小由Eden区、From 区向To 区复制时,对象大小大于To 可用内存,则把该对象转 存到老年代,且老年代的可用内存小于该对象大小
4)System.gc()方法的调用

17.什么是空间分配担保策略?

JVM在发生YGC之前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象的总空间,如果大于,则此次YGC是安全的;如果小于,则虚拟机会查看HandlePromotionFailure设置项的值是否允许担保失败。如果HandlePromotionFailure=true,那么会继续检查老年代最大可用连续空间是否大于历次晋升到老年代的对象的平均大小,如果大于则尝试进行一次Minor GC,但这次Minor GC依然是有风险的;如果小于或者HandlePromotionFailure=false,则改为进行一次Full GC。
在这里插入图片描述

18.JVM对象分配过程
在这里插入图片描述

19.垃圾回收器有哪些?常用搭配?
1)物理分代+逻辑分代:
serial 、serial Old、parallel Scavenge 、parallel Old、parNew、CMS
2)逻辑分代,物理不分代:
G1
3)其他:
ZGC、Shenandoah 、Epsilon(用于debug)

在这里插入图片描述

持续更新~~~~~~

各位大佬如果发现其中有问题可以留言或者私信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值