JVM八股
JVM
JVM的内存结构
元空间,Java 虚拟机栈,本地方法栈(虚拟机栈执行Java方法,本地方法站执行native方法),程序计数器,堆内存,直接内存
JVM内存模型里的堆和栈有什么区别
栈主要用于存储局部变量、方法调用的参数、方法返回地址以及一些临时数据栈中的数据具有确定的生命周期,当一个方法调用结束时,其对应的栈帧就会被销毁,栈中存储的局部变量也会随之消失
栈中存的是对象引用
堆分为哪几部分
新生代(Young Generation),新生代分为Eden Space和Survivor Space
老年代(Old Generation/Tenured Generation
元空间(Metaspace)
大对象区(Large Object Space / Humongous Objects
方法区中的方法的执行过程
解析方法调用
栈帧创建
执行方法:
返回处理
对方法区(Method Area)存储内容描述如下:它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等
String 保存在字符串常量池中
内存泄露常见原因:
使用静态数据结构(如HashMap或ArrayList)存储对象,且未清理。
未取消对事件源的监听,导致对象持续被引用。
未停止的线程可能持有对象引用,无法被回收。
内存溢出常见原因:
大量对象创建:程序中不断创建大量对象,超出JVM堆的限制。
持久引用:大型数据结构(如缓存、集合等)长时间持有对象引用,导致内存累积。
递归调用:深度递归导致栈溢出
Java中创建对象的过程
类加载检查,分配内存,初始化零值,进行必要设置,比如对象头,执行 init 方法
类加载器
启动类加载器(Bootstrap Class Loader),扩展类加载器(Extension Class Loader),系统类加载器(System Class Loader)/ 应用程序类加载器(Application Class Loader),自定义类加载器(
Custom Class Loader)
双亲委派模型的作用
保证类的唯一性,保证安全性,支持隔离和层次划分,简化了加载流程
类加载过程
加载:通过类的全限定名(包名 + 类名),获取到该类的.class文件的二进制字节流,
连接:验证、准备、解析 3 个阶段统称为连接,验证字节码,准备静态字段,解析符号成直接引用
初始化
使用
卸载
引用计数法和可达性分析算法
GC Roots对象包括:虚拟机栈(栈帧中的本地变量表)中引用的对象、方法区中类静态属性引用的对象、本地方法栈中JNI(Java Native Interface)引用的对象,活跃线程的引用
垃圾回收算法有哪些?
标记-清除算法
复制算法:
标记-整理算法
分代回收算法
垃圾回收器有哪些
CMS(Concurrent Mark Sweep)收集器(标记-清除算法): 老年代并行收集器,以获取最短回收停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最短GC回收停顿时间。
G1(Garbage First)收集器 (标记-整理算法): Java堆并行收集器,G1收集器是JDK1.7提供的一个新收集器,G1收集器基于“标记-整理”算法实现,也就是说不会产生内存碎片。此外,G1收集器不同于之前的收集器的一个重要特点是:G1回收的范围是整个Java堆(包括新生代,老年代),而前六种收集器回收的范围仅限于新生代或老年代
将GC分为三种类型:Minor GC(也称为Young GC)、Major GC(有时也称为Old GC)、以及Full GC
Minor GC (Young GC):只针对年轻代进行回收
major gc:主要针对老年代进行回收,但不一定只回收老年代
Full GC:对整个堆内存(包括年轻代、老年代以及永久代/元空间)进行回收。
垃圾回收器 CMS 和 G1的区别
CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用
CMS收集器以最小的停顿时间为目标的收集器
CMS收集器是使用“标记-清除”算法进行的垃圾回收,容易产生内存碎片
G1收集器使用的是“标记-整理”算法,进行了空间整合,没有内存空间碎片。
CMS适用场景:
低延迟需求,老生代收集,碎片化管理
G1适用场景
大堆内存,对内存碎片敏感,比较平衡的性能
JVM 的垃圾回收器不仅仅会对堆进行垃圾回收,它还会对方法区进行垃圾回收。