面试题--JVM垃圾回收及内存管理

选择题

1.以下哪些内存区域属于 JVM 规范?()

A. 方法区
B. 实例变量
C. 静态变量
D. 程序计数器
E. 虚拟机栈
正确答案:A D E
解析:
Java虚拟机规范划分了七个内存区域,其中根据是否为线程私有的分为两大类:
  1. 线程私有的:线程栈,本地方法栈,程序计数器
  2. 线程共享的:方法区,常量池,直接内存区,堆
其中常说堆和栈分别指的是线程栈和堆,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register)、Java栈(VM Stack)、本地方法栈(Native Method Stack)、方法区(Method Area)、堆(Heap)。

2 可以用于生成 JVM 进程堆快照的命令是?

A.jmap
B.jstack
C.jstat
D.jhat
正确答案:A
解析:
  • jmap 生成打印指定 Java 进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节
  • jstack 生成线程快照
  • jstat 命令可以查看堆内存各部分的使用量,以及加载类的数量
  • jhat 分析 java 堆的命令,可以将堆中的对象以 html 的形式显示出来

3.以下哪些 jvm 的垃圾回收方式采用的是复制算法回

A.新生代串行收集器
B.老年代串行收集器
C.并行收集器
D.新生代并行回收收集器
E.老年代并行回收收集器
F.cms 收集器
正确答案: A D
解析:
  • 两个最基本的java回收算法:复制算法和标记清理算法。
  • 复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。
  • 标记清理:一块区域,标记可达对象(可达性分析),然后回收不可达对象,会出现碎片,那么引出
  • 标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象。
  • 两个概念:新生代和年老代
  • 新生代:初始对象,生命周期短的;
  • 年老代:长时间存在的对象。
  • 整个java的垃圾回收是新生代和年老代的协作,这种叫做分代回收。
  • 新生代基本采用复制算法,年老代采用标记整理算法,CMS采用标记清理。

4jvm 中垃圾回收分为 scanvenge gc full GC,其中 full GC 触发的条件可能有哪些

A.栈空间满
B.年轻代空间满
C.老年代满
D.持久代满
E.System.gc()
正确答案: C D E
解析:
1,新生代:
(1)所有对象创建在新生代的 Eden 区,当 Eden 区满后触发新生代的 Minor GC,将 Eden 区和非空闲 Survivor 区存活的对象复制到另外一个空闲的 Survivor 区中。
(2)保证一个 Survivor 区是空的,新生代 Minor GC 就是在两个 Survivor 区之间相互复 制存活对象,直到 Survivor 区满为止。
2,老年代:当 Survivor 区也满了之后就通过 Minor GC将对象复制到老年代。老年代也满了的话,就将触发Full GC,针对整个堆(包括新生代、老年代、持久代)进行垃圾回收。
3,持久代:持久代如果满了,将触发 Full GC。

5 下面对 JVM 叙述不正确的是:

A.JVM 的全称是 Java Virtual Machine
B.JVM 是一种计算机硬件技术,它是 Java 程序的运行平台
C.JVM 是在计算机硬件系统上用软件实现的一台假想机
D.Java 程序在执行时.JVM 把 Java 字节码解释成机器码
正确答案:B
解析:

JVM 也就是 Java Virtual Machine,即 java 虚拟机, 是在现有的平台上,如Windows,Linux 等,运行一个软件,虚拟出一台接口统一的计算机,依次实现 java语言的跨平台特性

判断题

1. 调用 System.gc()之后会立即执行垃圾回收(×)

2. 程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,是线程隔离的(√)

3. Java 方法执行内存模型,用于存储局部变量,操作数栈,动态链接,方法出口等信息,是线程隔离的(√)

4. 方法区用于存储 JVM 加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,是线程隔离的 (×)

5. 原则上讲,所有的对象都在堆区上分配内存,是线程之间共享的(√)

解析:

运行时数据区包括:虚拟机栈区,堆区,方法区,本地方法栈,程序计数器虚拟机栈区 :也就是我们常说的栈区,线程私有,存放基本类型,对象的引用和 returnAddress ,在编译期间 完成分配。堆区 , JAVA 堆,也称 GC 堆,所有线程共享,存放对象的实例和数组, JAVA 堆是垃圾收集器管理的主要区域。 方法区 :所有线程共享,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。这个区域的内存回收目标主要是针对常量池的对象的回收和对类型的卸载。 程序计数器 :线程私有,每个线程都有自己独立的程序计数器,用来指示下一条指令的地址。

 

简答题

1java 类装载器的工作流程?

(1)当 AppClassLoader 加载一个 class 时,它首先 不会自己去尝试加载这个类,而是把类加载请求委派 给父类加载器 ExtClassLoader 去完成。

(2)当 ExtClassLoader 加载一个 class 时,它首先 也不会自己去尝试加载这个类,而是把类加载请求委 派给 BootStrapClassLoader 去完成。

(3)如果 BootStrapClassLoader 加载失败(例如在 $JAVA_HOME/jre/lib 里未查找到该 class),会使用 ExtClassLoader 来尝试加载;

(4)若 ExtClassLoader 也加载失败,则会使用 AppClassLoader 来加载 5、如果 AppClassLoader 也加 载失败,则会报出异常 ClassNotFoundException

2、运行时数据区包括哪几部分?哪些是线程私有的,哪些是共享的?

线程共享:Java 堆、方法区、常量池

线程私有:pc 寄存器、虚拟机栈、本地方法栈

3.如何判断一个对象是可以被回收的? 可达性分析

该方案是对象判活的主要方案基本思想就是将所引用的对象想象成一棵树,从树的根节点 GC Roots 出发持续遍历找出所有的树枝对象,这些对象被称之为"可达"对象或者 "存活对象",其余的对象则被视为"死亡"的不可达对象,或称"垃圾"GC Roots 本身一定是可达的,这样从他们出发 遍历到的对象才能保证一致可达,那么 Java 中哪一些对象一定是可达的呢?或者是哪一些可以作为 GC Roots 呢问题:可以作为 GC Roots 的对象虚拟机栈(帧栈中的本地变量表)中的引用的对象方法区中静态属性引用的对象方法区 中常量引用的对象本地方法栈中 JNI 引用的对象

4、论述 Java 中的几种引用类型,并说明每种引用类型的回收时机。

1)强引用:不会被回收

new一个Obiect存放在堆内存,然后用一个引用指向它,这就是强引用。如果一个对象具有强引用,那垃圾回收器就不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

2)软引用:仅在内存不足时,随时有可能被回收

如果一个对象只具有软引用,则内存空间足够时,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。

3)弱引用:随时有可能被回收

每次执行GC的时候,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

4)虚引用:随时有可能被回收

如果一个对象仅持有虚引用那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

5、新生代的回收方式?

由于新生代中的对象几乎都是朝生夕死”的(达 到 98%),现在的商业虚拟机都采用复制算法来回收 新生代。由于新生代的对象存活率低,所以并不需要 按照 11 的比例来划分内存空间,而是将内存分为 一块较大的 Eden 空间和两块较小的 From Survivor 空间、To Survivor 空间,三者的比例为 811。每 次使用 Eden From Survivor 区域,To Survivor 作 为保留空间。GC 开始时,对象只会存在于 Eden 区和 From Survivor 区,To Survivor 区是空的。GC 进行时, Eden 区中所有存活的对象都会被复制到 To Survivor 区,而在 From Survivor 区中,仍存活的对象会根据 它们的年龄值决定去向,年龄值达到年龄阀值(默认 为 15,新生代中的对象每熬过一轮垃圾回收,年龄值 就加 1)的对象会被移到老年代中,没有达到阀值的 对象会被复制到 To Survivor 区。接着清空 Eden 区和 From Survivor 区,新生代中存活的对象都在 ToSurvivor 区。接着, From Survivor 区和 To Survivor 区会交换它们的角色,也就是新的 To Survivor 区就是 上次 GC 清空的 From Survivor 区,新的 From Survivor 区就是上次 GC To Survivor 区,总之,不 管怎样都会保证 To Survivor 区在一轮 GC 后是空的。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值