Java-JVM-八股文

  1. 线程共享区
  2. 堆区与方法区是所有线程共享的
    栈区:主要存放基本数据类型与对象引用(仅限局部变量,成员变量不管是不是基本数据类型都存放于堆)
    堆区:主要存放对象实例与数组[我的理解就是,由代码操作生成的对象或者说引用类型存放于堆]
    方法区:类信息(class文件)、静态变量与静态方法
    本地方法栈:非静态方法
    
  3. 如何排查JVM问题
  4. 空间:jmap 查看 JVM各个区域的占用情况,查看是否栈区过大?是否堆区过大?
    时间:jstack 查看线程的运行情况,是否存在死锁或者阻塞?
    OOM:
    查看: jstat 查看垃圾回收情况,fullgc 与 younggc 的运行情况
    记录: JVM启动参数 --> -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/base,发生OOM的时候记录下当时的情况-dump文件,便于回溯定位问题
    分析:jvisualvm 可以针对dump文件进行分析异常对象,异常线程
    
  5. 从加载JVM到GC清理,一共经历什么过程-√
  6. 1.方法区加载字节码,加载静态方法、静态成员变量
    2.堆区创建实例化对象,保存至 年轻代 Eden 区
    3.将引用传回栈区
    4.经过minor GC,对象每次存活,年龄加一,并迁移至survival区-存活区,年龄大于等于15的时候,对象进入老年代
    5.栈区的引用被移除以后,对象最终被GC回收
    
  7. 如何确定对象是否需要回收
  8. 根可达算法:所有对象都是基于一个根对象上的,从根对象开始遍历,能找到引用的就是还需要的对象,否则就是不需要的对象。
    
  9. JVM垃圾回收机制
  10. 总共三种算法:
    标记:将所有对象判断是否根可达,将不可达对象标记并进行删除
    缺点:会有碎片空间出现
    
    复制法:申请一块与当前存储空间相同的空间,根可达算法标记所有存活对象,将存活对象迁移至新申请空间,迁移完毕以后,原空间统一清空
    缺点:需要的空间较大
    
    标记优化法:根可达算法标记所有存活对象,并将存活对象重新排列至连续空间,标记以及迁移排列完毕以后,将存活对象连续空间以外的空间统一清除
    
  11. 什么是STW
  12. STW,stop the world,即,在GC运行过程中,要将所有Java进程冻结,以便于GC进程进行垃圾回收。
    
  13. 常用的JVM启动参数有哪些?-※
  14. OOM有哪些情况?
  15. JVM共5片区域:堆、方法区、栈、本地方法区、程序计数器
    
    堆:
    1.大对象一直添加,同时GC来不及删除,就会OOM,例如,将10W条数据缓存到Java端
    2.内存泄漏,对象不使用,又没有被GC及时清除,例如threadlocal
    
    方法区:该区域用于存放字节码信息、运行时常量池、静态变量等等
    1.运行时常量池一直添加,也会导致OOM
    2.运行过程中,不断生成新的类,比如动态代理类,从而字节码信息增多,导致方法区OOM[或者项目实在太大了]
    
    栈:
    1.(stackOverflowError)最常见的OOM是由于无限递归引发的逻辑错误,导致栈一直申请内存空间,从而报 栈溢出错误
    2.(outOfMemeryError)如果允许动态扩展内存空间,当无法申请到更大的内存空间时
    
    本地方法区:本地方法栈与虚拟机栈融为一体 情况一致
    
    程序计数器(PC)是通过寄存器实现的,用于记录“当前线程”所执行代码,便于CPU线程切换时,能正确从被中断的位置继续执行
    如果线程正在执行的是一个Java方法,那么程序计数器记录的是正在执行的虚拟机字节码的地址。
    如果线程正在执行的是一个本地方法,那么程序计数器则为空。
    因为程序计数器只记录了当前执行的指令,所以不会发生OOM。
    
    以上都是基于JVM-5大区域进行分析,以下则是其他情况
    1.零拷贝(DMA),导致本机内存溢出
    2.线程申请过多,导致本机内存溢出
    
  16. 类加载的生命周期(类加载的过程)
  17. 从宏观上来说,分为 加载-验证-准备-解析-初始化 五个阶段
    
    加载:读取字节码文件,生成静态数据结构加载到方法区[1.8以后抛弃永久代的具体实现 改用元空间(原因 防止OOM?) 并将常量池与静态变量转移到堆],并在堆中生成便于用户调用的class对象,且通过双亲委派机制防止类的重复加载
    
    验证:字节码可以认为是一种中间代码,因此,只要符合字节码的要求,都可以被JVM加载,因此,加载字节码之后,需要验证其语法、语义是否正确[加载阶段验证文件格式 验证阶段验证元数据与字节码(类似语义分析) 解析阶段验证符号引用格式 这几个验证只是经典举例 随着语言发展 验证内容也在逐渐增多],该阶段的目的在于保证加载的字节码不会有害于JVM。
    
    准备:静态变量分配空间并设置默认值
    
    解析:符号引用转直接引用,类似于springboot里面的懒加载,直到解析阶段,对应的引用才转换成真实的地址引用。[一般是静态解析 多态用到动态解析]
    
    初始化:针对 成员变量与类变量 显式初始化的执行,以及静态代码块的执行
    
    
    方法区:抽象概念
    永久代\元空间:具体的实现方式
    
  18. 什么是三色标记
  19. 三色:白色 灰色 黑色
    
    白色:尚未被GC访问过的对象,刚开始根可达算法时,所有对象都是白色;根可达算法结束后,依然是白色的对象,视为不可达对象,应被清除
    灰色:被GC访问过的对象A,但是,A有成员变量对象还没有被访问过,是白色的
    黑色:对象及其成员变量都已被GC访问过,不可被回收
    
    
  20. 什么是安全点、安全区域
  21. 只有特定的位置能进行GC,这些位置,称之为“安全点”
    即,对象引用关系不再发生变化的位置
    
    安全区域是指在一段代码片段中,对象的引用关系不会发生变化,在这个区域中的任何位置开始GC都是安全的。
    我们也可以把Safe Region 看做是被扩展了的SafePoint。
    

参考:
1.https://blog.csdn.net/weixin_64366370/article/details/131160118
2.https://blog.csdn.net/qq578473688/article/details/77752080
3.https://blog.csdn.net/weixin_47184173/article/details/113576943
4.https://wsa.jianshu.io/p/87c2b6ea9d1b
5.https://www.bilibili.com/video/BV14U4y1L75q/?spm_id_from=333.337.search-card.all.click&vd_source=5c5bc2d817741ded0db4f222d4a03a7c

posted @ 2023-07-16 17:41  356a  阅读(51)  评论(0)    收藏  举报