【面试大全-JVM】必备JVM_jvm内存模型这块面试怎么准备,已获万赞

45 阅读7分钟

知识汇总

  • 需要了解 内存模型 各部分作用,保存哪些数据
  • 类加载双亲委派加载机制,常用加载器加载哪些类型的类
  • GC分代回收的思想、不同垃圾回收算法的思路
  • 性能调优及常有的参数作用,参数调优的依据和工具分析问题的使用方法。
  • 执行模式
  • 编译器优化
    在这里插入图片描述

Java内存模型

  • (线程独占):又称为方法栈,线程私有的,与线程同一时间创建,线程执行方法都会创建一个栈阵,用来存储局部变量表,调用方法时执行入栈,方法返回时执行出栈。,-Xss参数可以设置虚拟机栈大小。
  • 本地方法栈:与栈类似,也是用来保存执行方法的信息,执行Java方法是使用栈,实现Native方法是使用本地方法栈 C语言
  • 程序计算器:保存当前线程执行的字节码位置,每个线程工作时都有独立的计数器,只为Java方法服务,Native方法时程序计算器为空。
  • :JVM内存中管理最大的一块,对线程共享,目的是存放对象的实例,几乎所遇见的对象实例都会放在这里,当堆没有空间时,会抛出OOM异常,根据对象的存活周期不一样,JVM把对象进行分代管理,由垃圾回收器进行垃圾的回收管理。
  • 方法区(非堆区):线程共享的,用于存储已被虚拟机加载的类信息,常量,静态变量等。

说说类加载与卸载

  • 加载通过类的完全限定名,查找次类字节码文件,利用字节码文件创建Class对象
  • 验证当前Class文件符合当前虚拟机的要求,不会危害到虚拟机自身安全
  • 准备进行内存分配
  • 解析 将常量池中的符号引用替换
  • 初始化主要完成静态块执行及静态变量的赋值。
  • 加载机制:双亲委派模式,即加载器加载类时先把请求委托给自己的父类加载器执行,直到顶层的启动类加载器,父类加载器能够完成加载者成功返回,不能再进行子类加载。
  • 优点:避免类的重复加载、避免Java核心API被篡改
  • 分代回收:年轻代 、标记复制老年代、标记清除

JVM垃圾回收算法

  • G1算法
  • 1.9后默认的垃圾回收算法,特点是保持高回收率并减少停顿,采用每次只清理一部分,而不是清理全部的增量式清理,以保证停顿时间不会过长。
  • 其取消了新生代和老年代的物理划分,但任然属于分代收集器。
  • 同CMS相同,会遍历所有对象,标记引用情况,清楚对象后对区域进行复制移动,以整合碎片空间
  • ZBC算法

说说堆和栈的区别

  • 栈是运行时单位,代表着逻辑,内含基本数据类型和堆中的引用,所在区域连续,没有碎片。
  • 堆是存储单位,代表着数据,可被多个栈共享,所在区域不联系,碎片化。
  • 功能不同:栈用来存储局部变量和方法调用,而堆内存来存储Java中的对象,无论是成员变量、局部变量、还是类变量,它们指向的对象都是存储在堆内存中。
  • 共享性不一样:栈是线程私有的,堆是内存中共享的。
  • 异常错误不同:栈内存不足:StackOverFlowError、堆内存不住:OutOfMemoryError
  • 空间大小:栈的空间远远小于堆空间的大小

什么时候会发生FullGC

  • 直接调用 System.gc() 方法
  • 旧生代空间不足:新生代对象转入或创建大对象,当执行FullGC仍然内存不足时,抛出java.lang.OutOfMemoryError: Java heap space 错误
  • 永久代空间满时:当系统要加载的类、反射的类、和调用方法比较多时,永久代可能会被占满,如果还是不足则抛出: java.lang.OutOfMemoryError: PermGen space

什么是虚拟机,为什么Java叫与平台无关的语言

  • Java虚拟机是可以执行Java字节码的虚拟机进程,Java源文件被编译成Java虚拟机执行的字节码文件,Java编译后可实现跨平台,因为JVM虚拟机让这个变得可能。

谈谈对象分配规则

  • 对象有限分配在Eden区,如果没有足够的空间,则进行MinorGC
  • 大对象直接进入老年代,这样做是避免内存中进行拷贝(新生代采用复制算法收集内存)
  • 长期存活的对象进入老年代,

描述下JVM加载class文件原理机制

  • JVM的加载是由类加载器(ClassLoader)和它的子类来实现的,当Java程序需要某个类时,JVM确保这个类已经被加载、验证、准备、解析、初始化等操作,类加载就是把.class文件读取到内存中,通常创建一个字节数组进行存取。
  • 类加载机制采用了双亲委派机制进行加载、保证了平台的安全性。

关于类的生命周期

  • 加载、查找并加载二进制数据、在Java堆中创建一个Class类的对象。
  • 连接(验证、准备、解析)
  • 初始化:类赋值
  • 使用:new出对象
  • 卸载:执行垃圾回收

如何判断对象可以被回收

  • 引用计数:每个对象都有一个引用计算属性、新增一个引用+1,引用释放-1,计数为0时可以回收,次方法简单,无法解决对象互相引用问题。
  • 可达性分析:从GC Roots开始向下搜索,搜索所经过的路径称为引用链,当一个对象从GC Roots没有任何引用链时,则证明次对象是不可用的,可进行回收。

垃圾回收算法

  • 标记-清除算法:算法分别是标记和清除两个阶段、首先标记出所需要清理的对象,在标记完成后统一对标记的对象进行回收。
  • 复制算法:讲可用的容量划分为相等的两块,每次只使用其中的一块,当一块内存要用完了的时候,就将存活的对象复制到另一块上面,然后把已经使用过的一块全部清楚。
  • 标记-压缩算法:标记和标记-清除算法中一致,让所有存活的内存都移向一边,然后清理掉端边界以外的内存。
  • 分代收集算法:把堆内存分为新生代和老年代,这样可以根据不同年代的特点采用最适合的垃圾收集算法。

调优的命令有哪些

  • jps:显示指定系统内所有HotSpot虚拟机进程
  • jstat:用于监视虚拟机运行时状态命令,显示虚拟机内存,垃圾回收等。
  • jmap:生成 heap dump文件
  • jstack:生成当时的线程快照
  • jinfo:实时查看和调整虚拟机的运行参数

常见的调优工具

  • jconsole:jdk自带的监控控制台
  • Java VisualVM:内存快照、线程快照。
  • arthas 阿里巴巴开源 命令查看

为什么将-Xms和-Xmx设置为相同的值

  • 每次JVM增加堆大小时,它都必须向操作系统申请额外的内存,这会有一定的时间开销。
  • 使用较小的堆大小,使得GC更加的频繁,如果从最开始就设置大一些,GC就不会那也频繁。

逃逸分析

虚拟机为什么要使用元空间替换永久代

img img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取