JVM面试整理

文章目录

    • JVM面试整理
      • 1.内存泄漏
      • 2.内存溢出
      • 3.JVM常用参数有哪些?
      • 4.线上排查问题的一般流程是怎么样的?
      • 5.JVM 有哪些垃圾回收算法?
      • 6.说一下 JVM 有哪些垃圾回收器?
      • 7.说一下类加载的执行过程
      • 8. 什么是双亲委派模型?


JVM面试整理

1.内存泄漏

1. 什么是内存溢出

内存泄漏是指你向系统申请分配内存进行使用(new/malloc),然后系统在堆内存中给这个对象申请一块内存空间,但当我们使用完了却没有归系统(delete),导致这个不使用的对象一直占据内存单元,造成系统将不能再把它分配给需要的程序

2. 内存溢出的原因

  • 大量使用静态变量
  • 连接资源未关闭
  • ThreadLocal的错误使用

3. 内存溢出的危害

内存泄漏的堆积,最终消耗尽系统所有的内存。

2.内存溢出

指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用,此时就会报错OOM,即所谓的内存溢出。

3.JVM常用参数有哪些?

  • Xms 初始堆大小,JVM启动的时候,给定堆空间大小

是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的快一点,但是也可能会导致机器暂时间变慢

  • Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常
  • Xss 是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程大约需要占用多少内存,可能会有多少线程同时运行等
  • -Xmn:堆内新生代的大小

整个堆大小 = 年轻代大小 + 老年代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。

  • -XX:NewSize=n

设置年轻代初始大小

  • -XX:NewRatio=4

设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。**设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5

  • -XX:PermSize=100m

初始化永久代大小。

-XX:PermSize=100m:初始化永久代大小为100MB

  • -XX:MaxPermSize

设置永久代最大大小

-XX:MaxPermSize=256m:设置永久代最大大小256MB。

  • -XX:+UseConcMarkSweepGC

使用CMS垃圾回收器

  • -XX:+UseParallelGC

使用并行垃圾回收器

  • -XX:+UseG1GC

使用G1垃圾回收器

4.线上排查问题的一般流程是怎么样的?

1. CPU占用过高排查流程

  1. 利用 top 命令可以查出占 CPU 最高的的进程pid ,如果pid为 4321
  2. 然后查看该进程下占用最高的线程id【top -Hp 4321】
  3. 假设占用率最高的线程 ID 为 6900,将其转换为 16 进制形式 (因为 java native 线程以 16 进制形式输出) 【printf ‘%x\n’ 6900】
  4. 利用 jstack 打印出 java 线程调用栈信息【jstack 9876 | grep ‘0x1af4’ -A 50 --color】,这样就可以更好定位问题

2. 内存占用过高排查流程

  1. 查找进程id: 【top -d 2 -c】
  2. 查看JVM堆内存分配情况:jmap -heap pid
  3. 查看占用内存比较多的对象 jmap -histo pid | head -n 100
  4. 查看占用内存比较多的存活对象 jmap -histo:live pid | head -n 100

5.JVM 有哪些垃圾回收算法?

  • 标记-清除算法:标记有用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片。
  • 复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半,消耗内存。
  • 标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。
  • 分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本采用复制算法,老年代采用标记整理算法。

6.说一下 JVM 有哪些垃圾回收器?

  1. Serial收集器:它是最古老的垃圾回收器,采用单线程进行垃圾回收,在回收过程中暂停所有的应用线程,适用于小型的应用场景。
  2. Parallel收集器:它是Serial收集器的改进版,使用多线程进行垃圾回收,在回收过程中会暂停所有的应用线程,适用于多核CPU的服务器应用场景。
  3. CMS收集器: 老年代并行收集器,它是一种以获取最短回收停顿时间为目标的垃圾回收器,使用多线程进行垃圾回收,在回收过程中只暂停少量的应用线程,适用于响应时间敏感的应用场景
  4. G1收集器:G1回收的范围是整个Java堆(包括新生代,老年代),使用分代收集算法进行垃圾回收,在回收过程中只暂停少量的应用线程,适用于大型的内存应用场景。
  5. ZGC收集器:它是JDK11中新引入的一种垃圾回收器,以获取最短回收停顿时间为目标,可以在不超过10ms的停顿时间内进行全堆垃圾回收,适用于超大型的内存应用场景。

7.说一下类加载的执行过程

  1. 加载:根据查找路径找到相应的 class 文件然后装载入内存中;
  2. 验证:检查加载的 class 文件的正确性;
  3. 准备:给类中的静态变量分配内存空间;
  4. 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;
  5. 初始化:对静态变量和静态代码块执行初始化工作。

8. 什么是双亲委派模型?

  • 当需要加载一个类的时候,子类加载器并不会马上去加载,而是依次去请求父类加载器加载
  • 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器;
  • 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。

你可能感兴趣的:(jvm,面试,职场和发展)