深入理解JVM:内存模型与垃圾收集

需积分: 9 1 下载量 78 浏览量 更新于2024-09-03 收藏 2.28MB DOCX 举报
"这份文档是关于JVM的专题,主要涵盖了面试中常见的JVM知识点,包括方法的入栈出栈、堆内存分代、运行时数据区、Java内存模型JMM、OOM问题的排查、GC调优策略、JDK8默认的垃圾收集器以及FullGC的触发原因和GC算法等。" 1. **方法进栈出栈的步骤** 在Java中,每当一个方法被调用时,都会创建一个栈帧(Stack Frame)并压入虚拟机栈。栈帧包含了局部变量表、操作数栈、动态链接、方法出口等信息。当方法执行完毕,对应的栈帧会被弹出,返回结果给调用者。 2. **堆内存分代** 堆内存通常分为新生代(Young Generation)、老年代(Tenured Generation或Old Generation)和永久代( Perm Generation,在JDK8后改为元空间MetaSpace)。新生代又细分为Eden区和两个Survivor区(From和To),大部分对象在Eden区分配,经历一次 Minor GC 后,存活的对象会被移到Survivor区,多次存活的对象则晋升到老年代。 3. **运行时数据区** Java虚拟机的运行时数据区包括程序计数器、虚拟机栈、本地方法栈、堆和方法区(在JDK8后变为元空间)。每个线程都有自己独立的程序计数器和虚拟机栈,而堆和方法区是所有线程共享的。 4. **Java实例与数据区** Java实例(对象)通常存放在堆内存中,无论是通过`new`关键字创建的还是通过其他方式。新生代的对象首先分配在Eden区,然后经过垃圾收集和晋升机制进入老年代。 5. **Java内存模型JMM** Java内存模型(Java Memory Model,JMM)定义了线程如何访问共享变量,确保多线程环境下的可见性、有序性和原子性。它规定了 volatile、synchronized 和 final 关键字的行为,以及内存屏障等概念。 6. **OOM问题的排查** 当出现内存溢出问题时,可以使用`top`命令监控内存使用,`jstack`分析线程状态,`jmap -heap`查看堆内存分配,`jmap -histo`或在线工具分析对象占用,以及通过GC日志进一步诊断。 7. **GC调优思路** 调优首先需要配置GC日志输出,然后分析吞吐量、平均暂停时间和GC次数。根据业务需求调整堆内存大小,选择合适的垃圾收集器。例如,G1收集器允许设置停顿时间目标,通过观察吞吐量和平均暂停时间进行优化。 8. **JDK8默认垃圾收集器** JDK8默认使用ParallelGC,新生代使用ParallelScavenge,老年代使用ParallelOld。可以通过`java -XX:+PrintCommandLineFlags -version`查看具体设置。 9. **应用启动时的FullGC** 应用启动时发生的FullGC可能是因为元空间不足。元空间用于存储类信息,如果设置过小且类信息过多,会导致元空间扩展,进而触发FullGC,包括MinorGC、OldGC和MetaspaceGC。 10. **GC算法和回收原理** Java中的垃圾收集算法包括标记-清除、复制、标记-整理和分代收集等。这些算法旨在高效地回收不再使用的对象,减少内存碎片,同时保持较低的暂停时间。不同的垃圾收集器如Serial、Parallel、CMS、G1等采用了不同的回收策略。