JVM常见面试题

说说JVM对象创建与内存分配的流程

首先经过类加载检查,将需要的类加载到jvm内存中,即经过加载、验证、准备、解析、初始化

其次分配内存(指针碰撞/空闲列表)

再初始化(给成员变量赋初始值null/0)

之后设置对象头

最后执行init()方法

内存分配采用的方法

指针碰撞

内存空间分配规则时,有一个已使用和未使用的临界指针,分配内存时只需要往后空出几个空间。这就是指针碰撞

空闲列表

内存分配不规则时,已被使用的内存和空闲的内存交错在一起,虚拟机就会维护一个列表,记录可用的内存空间。当对象创建时,就可以找到空闲的内存进行分配

在并发对象创建时的处理流程

CAS乐观锁+失败重试

多个线程一起抢内存空间,只能有一个线程抢到,其他线程再去抢其他的内存空间

本地线程分配缓冲

每个线程都在堆中事先规划一块独立的线程专属空间,线程在new对象时,只向自己的内存空间存放,也就是jvm需要开启TLAB

对象内存分配流程

线程new对象时,会先进行对象逃逸分析,非对象逃逸的话优先存放去栈上,如果栈上分配不下的话,还是会在堆上分配

在堆上分配优先存放Eden区(TLAB本地线程缓冲),但如果对象太大会分配到老年代

长期存活的对象直接进入老年代(默认经过15次FullGC)。

ThreadLocal为什么会导致内存泄漏?如何解决的?

ThreadLocal的作用,可以在这个线程中被线程的方法调用,类似缓存。每个线程中都有一个ThreadLocalMap属性,key值为ThreadLocal,value为缓存值。key值是弱引用,value值是强引用,GC时会清除弱引用,但是强引用value不会被清除。

在线程池中,一旦给ThreadLocalMap赋值了,没有手动remove(),那么就会造成内存泄漏的问题。

解决方法:

手动执行remove()方法。

避免线程池中使用ThreadLocalMap。

平时要做好监控和预防。

什么是三色标记?

是CMS的底层算法逻辑。

分为黑色、灰色、白色

黑色:表示对象和它引用的对象都已被检查且都是可达的

灰色:表示对象已被检查是可达的,但是它引用的对象未被检查

白色:表示对象和它引用的对象都未被检查。白色对象可能是垃圾,直到它被证明为可达的

说说你们生产环境遇到的哪些JVM内存问题?是怎么解决的?

内存泄漏,线程池中使用了ThreadLocalMap,未手动remove()

频繁fullGC问题,一个高并发的系统,由于老年代内存不足,导致频繁Full GC,解决方法:

1、调整堆内存配置,增加老年代内存空间

2、优化对象的生命周期,减少不必要的对象创建

内存碎片的问题:批处理调度,频繁创建和释放大对象,导致内存碎片化

解决方法:

1、调整内存配置,增加连续内存块的大小

2、减少大对象的频繁分配和释放

3、使用G1垃圾回收器(底层采用复制算法)

4、CMS垃圾回收器(底层采用标记清除算法),可修改参数更改为标记整理算法,减少内存碎片的产生

相关推荐
Satan7122 小时前
【Spring】Spring Aop基础入门
java·开发语言·jvm
这河里吗l2 小时前
Java每日面试题(JVM)(day15)
java·开发语言·jvm·笔记·后端
Satan7123 小时前
【Java】JVM基本组成
java·开发语言·jvm
吾爱星辰8 小时前
【解密 Kotlin 扩展函数】扩展函数的底层原理(十八)
java·开发语言·jvm·kotlin
Vacancy空白9 小时前
tomcat项目【jvm内存溢出】
linux·jvm·tomcat
生产队队长10 小时前
JVM(HotSpot):程序计数器(Program Counter Register)
开发语言·jvm·python
森屿Serien10 小时前
jvm 内存结构
java·jvm
冷酷无情小美10 小时前
JVM类加载机制
jvm
zheeez10 小时前
JVM 基本组成
java·jvm
程序猿阿伟15 小时前
《C++无锁编程:解锁高性能并发的新境界》
java·jvm·c++