总结一些容易被遗忘的基础知识,适合有一定Java基础的技术人员阅读。有些内容可能对初学者来说比较困难,希望能帮助大家轻松应对面试官的基本技术问题,提高编码效率。 JVM基础1、内存模型(1)程序计数器:线程私有、CPU调度的基本单位,用于保证线程切换(多线程环境下程序可连续执行); (2)栈(服务Java法虚拟机栈,服务Native法本地方法栈):线程私有,局部变量/引用,栈深(SOF)/无法申请内存(OOM); (3)堆(Java代码可及的Java堆和JVM本身使用的方法区):线程共享、对象分配和回收主要区域、OOM; 2、垃圾回收机制。(1)Stop-the-World。 JVM因执行GC而停止执行应用程序称为Stop-the-world,这种情况发生在任何GC算法中。当Stop-the-world发生时,除了GC所需的线程外,所有线程都处于等待状态,直到GC任务完成。事实上,GC优化往往是指减少Stop-the-world的发生时间,使系统具有高吞吐量、低停顿的特点。 (2)回收JAVA堆。 Java对象的回收主要考虑以下两个问题:哪些对象可以回收,如何回收(哪些回收算法和垃圾回收器)。 ①判断对象是否可以回收:引用计数法数法(相互引用)、可达性算法(对象引用链是否可达,GCRoots) ②垃圾回收算法:标记清除算法(内存碎片)、复制算法(垃圾回收频繁、对象存活率低的新一代)、标记整理算法(垃圾回收不频繁、对象存活率高的老年人)、分代收集算法。 ③垃圾回收器:串行收集器(新生代、老年代)、并行收集器(新生代、老年代)、并行清除收集器(并发、新生代、追求高吞吐量)、CMS收集器(并发、老年、标记-清除算法、追求低停顿)、G1垃圾收集器(整堆,追求低停顿) 附: GCRoots一般包括虚拟机栈中引用的对象、本地方法栈中引用的对象、方法区中类静态属性引用的对象、方法区中常引用的对象。 附: GCRoots一般包括虚拟机栈中引用的对象、本地方法栈中引用的对象、方法区中类静态属性引用的对象、方法区中常引用的对象。 分代收集算法的基本思想是:不同对象的生命周期(生存条件)不同,不同生命周期的对象位于堆中的不同区域。因此,采用不同的策略回收堆内存的不同区域可以提高JVM的执行效率。MinorGC的发生频率很高,不一定等到Eden区域满了才触发;MajorGC在老年人满时触发,回收年轻人和老年人。 (3)方法区回收。 ①回收常量池。 ②卸载类型:这类的所有实例都被回收,这类Classloader被回收,对这类Class对象没有引用。 3、OOM/SOF。(1)OOMforHeap:内存泄露(GCRoots的引用链,对象的生命周期超出预期)或内存溢出(调整JVM参数-X、-Xmx等。 (2)OOMforStack:一般不会出现在单线程序中;在多线程环境下,无法申请足够的内存来创建线程。 SOFforStack:程序是否有深度递归。 (4)OOMforPerm:使用Spring等框架时,往往会动态生成大量类别,导致永久代不足,导致OutOfmemoryError:PermgenSpace异常(调大-XX:MaxPermSize) |
|