jvm面试问题及我的答案

今天在技术群里被大佬问了一堆jvm的问题。。收集记录下来。。并且附上我的答案(没有百度的,不可尽信,仅仅是我看《深入理解java虚拟机》的粗浅回答)

1、堆被分成了新生代和老年代,什么对象会进入老年代。

答:

(1)大对象(对象大小超过设定的阈值),直接到老年代。

(2)在年轻代survivor区域存活minor gc次数超过指定次数的对象。默认是15次。可通过参数设置。

(3)survivor中存活的对象,存活次数相同的对象内存总和大小超过survivor的一半,那么大于等于这个存活次数的对象都会进入到老年代。

2、如何判断对象是否可回收?

(1)根据GC roots 进行可达性分析。

3、哪些对象可以做GC roots?

(1)、虚拟机栈中的每个栈帧中的局部变量表中的对象(即正在被调用的方法中的局部变量)

(2)、方法区中静态变量

(3)、方法区运行时常量池里的引用类型常量。(运行时常量池除了String和其他基本类型的包装类,还有啥引用类型?而String和包装类是不可变的啊)

(4)、本地方法栈中使用的对象。(这个不懂)

4、如何解决内存泄漏?

这个就要好好利用jdk本身提供的jmap工具了。

(1)用jmap把堆的当前快照文件拿到。

(2)使用专门的工具解析这个快照文件,貌似jdk里也有一个工具可以简单解析,转为图形界面。

(3)使用jmap本身参数可以查看占用内存对象。

(4)定位到具体代码,然后修改代码。

5、死锁如何解决?

使用jstack工具可以查询当前堆栈信息,并且会判断死锁标识。。

阿里开源的arthas也可以查看。。

6、触发gc的条件有哪些?

(1)年轻代内存不够了,触发minor GC

(2)老年代内存不够了,触发full GC/major GC

(3)方法区(永久代)内存不够了,触发Full GC

(4)minor GC时,如果有存活对象要晋升到老年代,如果老年代剩余空间大小小于历次平均晋升的对象大小,那么老年代会进行GC,此时是Full GC。

(5)代码中使用System.gc,会建议垃圾收集进行GC,但GC不一定听取建议。。不过在满足某些条件时还是会听取建议的(项目中一般不显示这么调用,本来就不一定立即生效)

(6)所谓大对象,是指需要大量连续内存空间的java对象,例如很长的数组,此种对象会直接进入老年代,而老年代虽然有很大的剩余空间,但是无法找到足够大的连续空间来分配给当前对象,此种情况就会触发JVM进行Full GC。

发布了144 篇原创文章 · 获赞 36 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_36951116/article/details/103809762