更新时间:2023-01-30 15:47:26 来源:极悦 浏览1622次
1.JVM内存模型
整体描述上面对运行时数据区描述了很多,其实重点存储数据的是堆和方法区(非堆),所以内存的设计也着重从这两方面展开(注意这两块区域都是线程共享的)。对于虚拟机栈,本地方法栈,程序计数器都是线程私有的
(1) 一块是非堆区,一块是堆区
(2) 堆区分为两大块:一个是old区,一个是Young区
(3) Young区分为两大块: 一个是survivor区 (S+S1) ,一块是Eden区
(4) S和S1一样大,也可以叫From和To
2.JVM使用“类”的生命周期是:
装载、链接、初始化、使用、卸载
1.装载:
定要找到Class文件所在的全路径,然后装载到内存中J,ava又是一门面向对象的开发语这个过程用到了类加载器 ClassLoader。
2.连接 该阶段又包含了验证、准备和解析3个过程,如下。
(1)验证
校验.class文件的正确性。
(2)准备
2.1给static静态变量分配内存,并初始化static的默认值。
private static int a=10; 此时a变量会被赋值为默认值
2.2符号引用和直接引用
符号引用:4f62 6a65 6374 ----->loading 二进制流是没有办法被cpu直接解析的 (.class 变量 方法等等里面全是二进制的)
直接应用:0x00ab---0x00ba 物理内存
3.初始化:给static变量 赋予实际的值
private static int a=10; a=10;
4.使用:对象的初始化、对象的垃圾回收、对象的销毁.
3、GC Roots 有哪些?
1、 GC Roots 是一组必须活跃的引用。用通俗的话来说,就是程序接下来通过直接引用或者间接引用,能够访问到的潜在被使用的对象。
2、 GC Roots 包括:Java 线程中,当前所有正在被调用的方法的引用类型参数、局部变量、临时值等。也就是与我们栈帧相关的各种引用。所有当前被加载的 Java 类。Java 类的引用类型静态变量。运行时常量池里的引用类型常量(String 或 Class 类型)。JVM 内部数据结构的一些引用,比如 sun.jvm.hotspot.memory.Universe 类。用于同步的监控对象,比如调用了对象的 wait() 方法。JNI handles,包括 global handles 和 local handles。
3、 这些 GC Roots 大体可以分为三大类,下面这种说法更加好记一些:活动线程相关的各种引用。类的静态变量的引用。JNI 引用。
4、 有两个注意点:我们这里说的是活跃的引用,而不是对象,对象是不能作为 GC Roots 的。GC 过程是找出所有活对象,并把其余空间认定为“无用”;而不是找出所有死掉的对象,并回收它们占用的空间。所以,哪怕 JVM 的堆非常的大,基于 tracing 的 GC 方式,回收速度也会非常快。
4.垃圾收集算法进行垃圾收集
标记-清除算法
分为标记和清除阶段,首先从每个 GC Roots 出发依次标记有引用关系的对象,最后清除没有标记的对象。
执行效率不稳定,如果堆包含大量对象且大部分需要回收,必须进行大量标记清除,导致效率随对象数量增长而降低。
存在内存空间碎片化问题,会产生大量不连续的内存碎片,导致以后需要分配大对象时容易触发 Full GC。
标记-复制算法
为了解决内存碎片问题,将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当使用的这块空间用完了,就将存活对象复制到另一块,再把已使用过的内存空间一次清理掉。主要用于进行新生代。
实现简单、运行高效,解决了内存碎片问题。代价是可用内存缩小为原来的一半,浪费空间。
HotSpot 把新生代划分为一块较大的 Eden 和两块较小的 Survivor(s0,s1),每次分配内存只使用 Eden 和其中一块 Survivor(s0和s1 永远只有一个有值)。垃圾收集时将 Eden 和 Survivor 中仍然存活的对象一次性复制到另一块 Survivor 上,然后直接清理掉 Eden 和已用过的那块 Survivor。HotSpot 默认Eden 和 Survivor 的大小比例是 8:1,即每次新生代中可用空间为整个新生代的 90%。
标记-整理算法
标记-复制算法在对象存活率高时要进行较多复制操作,效率低。如果不想浪费空间,就需要有额外空间分配担保,应对被使用内存中所有对象都存活的极端情况,所以老年代一般不使用此算法。
老年代使用标记-整理算法,标记过程与标记-清除算法一样,但不直接清理可回收对象,而是让所有存活对象都向内存空间一端移动,然后清理掉边界以外的内存。
标记-清除与标记-整理的差异在于前者是一种非移动式算法而后者是移动式的。如果移动存活对象,尤其是在老年代这种每次回收都有大量对象存活的区域,是一种极为负重的操作,而且移动必须全程暂停用户线程。如果不移动对象就会导致空间碎片问题,只能依赖更复杂的内存分配器和访问器解决。
以上就是“Java jvm类面试题,超级详细的整理”,你能回答上来吗?如果想要了解更多的相关内容,可以关注极悦Java官网。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习