JVM知识点梳理

1.JVM虚拟机组成部分有哪些? Java运行时数据区包含哪些部分?各部分作用?是否存在GC及OOM问题

  • jvm组成部分:类加载器、运行时数据区、执行引擎

  • 运行时数据区:方法区、堆、栈、程序计数器、本地方法栈

  • 方法区:共享,存储由字节码文件解析出来的类型信息、常量、静态变量,

  • 堆:共享,存储实例变量和数组,空间区域分为新生代和老年代,通过垃圾回收机制来进行管理,存在GC,存在OOM

  • :私有,存储的是对象的引用,每个线程会有独立的栈,每一个方法执行都会被放在栈中(先进后出),cpu在不同线程之间运行时,各自栈都会通过各自的栈帧来记录方法执行的步骤,存在OOM

栈帧:用于存储局部变量表、操作栈、动态链接、方法出口等信息

  • 程序计数器:私有,记录当前线程执行到了哪一步

  • 执行引擎Execution Engine执行引擎负责解释命令,提交操作系统执行。

  • 本地方法栈:私有,支持native方法的执行

2.类加载器有哪些?什么是双亲委派机制?有什么好处?

类加载器负责加载class文件,class文件在文件开头有特定的文件标示,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。

类加载器的分类:

  • 启动类加载器:负责加载Java核心类库(如java.lang、java.util等)。C++

  • 扩展类加载器:负责加载Java的扩展类库(如javax包中的类)。

  • 应用程序类加载器:负责加载应用程序的类,通常是通过加载classpath中指定的jar包及目录中class来加载的。

  • 自定义加载器:通过继承java.lang.ClassLoader类的方式定制类的加载方式,可以根据需要加载特定的类文件。

双亲委派机制

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上

  • 1、当AppClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。

  • 2、当ExtClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader去完成。

  • 3、如果BootStrapClassLoader加载失败(例如在$JAVA_HOME/jre/lib里未查找到该class),会使用ExtClassLoader来尝试加载;

  • 4、若ExtClassLoader也加载失败,则会使用AppClassLoader来加载

  • 5、如果AppClassLoader也加载失败,则会报出异常ClassNotFoundException

好处

  • 这种机制保证了类的唯一性和安全性,避免了类的重复加载和版本冲突问题。

3.类加载过程?

Java的类加载过程是指将Java类的字节码文件(.class文件)从文件系统中读取到JVM(Java虚拟机)中,并将其转换为JVM可以直接识别的数据结构的过程。整个过程可以大致分为七个阶段:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)。

4.堆内存细分为哪些区域,各区域存放对象特点?

  • 可以分为新生代和老年代

  • 新生代:生命周期短,比较活跃

  • 老年代:生命周期长,内存大

5.对象直接进入老年代的情况有哪些?

新到老(三种模式):

  • 根据垃圾处理时的存活轮数,存活一轮年龄值加一,若年龄值>15则变为老年代

  • 新new的对象会被放入新生代区,若新生代中内存满了,就会触发新生代的垃圾回收,进行垃圾回收,清理了垃圾,有内存了,则将对象放入新生代中,内存仍不足,则会把新new的对象放入老年代中。

  • 新new的对象会被放入新生代区,若新new的对象太大,新生区内存不足,此时会触发新生代的垃圾回收,进行垃圾回收,清理后仍不够,则会直接把新new的对象放入老年代中。

    • 若往老年代存放时,老年代内存不足,则会触发老年代进行垃圾回收,清理了垃圾,有内存了,则将对象放入老年代中,内存仍不足,则抛异常OOM堆溢出。

    • 故老年代若触发了垃圾回收,新生代一定触发过;新生代触发了,老年代不一定触发。

6.如何判断一个对象是否可回收?可达性分析法工作原理,哪些是GCRoots根?

  • 可达性分析算法:以栈中的变量为根节点向下进行遍历,若对堆中的对象有引用关系,则会对对象进行标记,没有被标记的对象就会视为垃圾。

没有被标记的不一定会被清除回收,在回收对象时,会考虑其他因素,比如对象的finalize()方法是否被调用过,如果未执行,则会先执行finalize()方法。在finalize()方法中,对象可以通过与GC Roots建立引用关系来逃脱垃圾回收。但需要注意的是,finalize()方法只会被执行一次。

在Java语言中,可以作为GC Roots的对象包括下面几种:

  • 虚拟机栈(栈帧中的本地变量表)中的引用对象。

  • 方法区中的类静态属性引用的对象。

  • 方法区中的常量引用的对象。

  • 本地方法栈中JNI(Native方法)的引用对象

7.垃圾回收算法及优缺点?为什么要分代垃圾回收?

  • 标记清除:

    遍历堆中的对象,找出没有被标记的对象,进行统一清理,会产生碎片

    优点:速度比较快

    缺点:会产生内存碎片,碎片过多,仍会使得连续空间少

    标记和清除过程需要暂停应用程序,对性能有一定影响。

  • 标记整理:

    遍历堆中的对象,找出没有被标记的对象,边清理边移动,避免了碎片的产生,但是在移动对象时会触发"stop the world STW"(停止所有用户线程),效率较低

    优点:无内存碎片

    缺点:标记和整理过程也需要暂停应用程序,效率较低

  • 复制算法:

    在堆里面开辟两份大小相等空间(from区和to区),一份空间始终空着,垃圾回收时,将存活对象拷贝进入空闲空间;边清理边拷贝

    优点:无内存碎片

    缺点:占用空间多,内存利用率低

    当存活对象较多时,复制过程会消耗大量时间。

  • 年轻代特点是区域相对老年代较小,对象存活率低,生命周期短。

    这种情况复制算法的回收整理,速度是最快的。复制算法的效率只和当前存活对象大小有关,因而很适用于年轻代的回收。而复制算法内存利用率不高的问题,通过hotspot中的两个survivor的设计得到缓解。

    老年代的特点是区域较大,对象存活率高,生命周期较长。

    这种情况,存在大量存活率高的对象,复制算法明显变得不合适。一般是由标记清除或者是标记清除与标记整理的混合实现。

8.标记对象三色标记法是什么?

三色标记法基于对象的可达性分析,将对象标记为三种颜色之一:白色、灰色、黑色,以此来表示垃圾回收过程中的不同状态。

  • 白色:没有进行可达性分析之前都时白色

  • 灰色:在进行可达性分析时,被引用的对象会标记为灰色

  • 黑色:在进行可达性分析时,若灰色节点下的子节点全变为灰色时,则此灰色节点就会变为黑色

9.怎么排查堆OOM问题?

①错误名称

java.lang.OutOfMemoryError,也往往简称为 OOM。 这个错误指的是:“内存溢出”,并不是专门指“堆溢出”这么一个情况。

②错误信息
  • Java heap space:针对整个堆进行Full GC后,内存空间还是放不下新产生的对象,且无法申请更多的空间

  • PermGen space:永久代溢出。方法区中加载的类太多了(典型情况是框架创建的动态类太多,导致方法区溢出)

  • Metaspace:元空间溢出。方法区中加载的类太多了(典型情况是框架创建的动态类太多,导致方法区溢出)

  • Direct Memory space:直接内存溢出

可以采取以下步骤:

1、收集错误信息:首先查看应用程序的日志文件,寻找与内存相关的错误信息。通常OOM异常会在日志中有相应的记录,包括堆栈跟踪和错误消息。

2、分析堆转储文件:当应用程序发生OOM异常时,JVM通常会生成一个堆转储文件(Heap Dump),其中包含了应用程序在发生异常时的内存快照。

3、使用内存分析工具:将生成的堆转储文件导入到内存分析工具中,如Eclipse Memory Analyzer(MAT)、YourKit Java Profiler、VisualVM Heap Dump

Analyzer等。这些工具可以帮助分析堆转储文件,查找内存泄漏、大对象、对象引用关系等问题。

4、检查内存使用情况:通过内存分析工具,查看应用程序的内存使用情况,包括堆内存、非堆内存、对象数量、对象大小等指标。特别关注内存占用较高的对象或数据结

构,以及是否存在异常的内存增长趋势。

5、查找内存泄漏:使用内存分析工具,检查堆转储文件中的对象引用关系,查找可能导致内存泄漏的对象。特别关注长时间存活的对象、被遗忘的引用、缓存对象等。

6、优化内存使用:根据分析结果,进行相应的优化措施。例如,减少对象的创建和销毁、优化数据结构、调整缓存策略、增加堆内存大小等。

7、监控和测试:在优化后,持续监控应用程序的内存使用情况,并进行性能测试,以确保问题已经解决或得到改善。

需要注意的是,OOM异常可能有多种原因,如内存泄漏、内存溢出、过度使用第三方库等。因此,在定位OOM异常时,需要综合考虑多个因素,并进行适当的分析和测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值