1.频繁 minorgc怎么处理?**
优化MinorGc频繁的问题:通常情况下,由于新生代空间较小,Eden区很快被填满,就会导致频繁minorGc,因此可以通过增大新生代空间。-Xmn来降低MinorGc的频率。
2.频繁FullGc怎么处理?
FullGc的排查思路如下:
1)清楚从程序的角度,有哪些原因导致FullGc.
①大对象:系统一次性加载了过多的数据到内存中(比如sql查询未分页)导致大对象进入到老年代。
②内存泄漏:频繁的创建了大量对象,但是无法回收(比如Io对象使用完后未调用close方法释放资源),先引发FullGc,最后导致OOM
③程序频繁生成一些长生命周期的对象:当这些对象的存活年龄超过分代年龄便会进入老年代,最后引发FullGc.
④程序bug
⑤代码中显式调用gc方法,包括自己的代码甚至框架中的代码
⑥JVM参数设置问题:包括总内存大小,新生代和老年代大小,Eden区和S区的大小,元空间大小,垃圾回收算法等。
3.如何处理内存溢出(OOM)问题,如何定位?
内存泄漏是内在病原,外在病症表现可能有:
①应用程序长时间连续运行时性能严重下降
②CPU使用率飙高,甚至到100%
③频繁FullGC,各种报警
④应用程序抛出OutOfMemoryError错误
⑤应用程序偶尔会耗尽连接对象
严重的内存泄漏往往伴随频繁的FullGc,所以分析排查内存泄漏问题首先从查看FullGc入手。
1)使用jps 查看运行的Java进程Id
- 使用top -p 【pid】查看进程使用cpu和内存情况
3)使用top -H -p [pid] 查看进程下所有线程占CPU和内存的情况
4.如何定位线上OOM?
OOM产生原因
①一次性申请的太多
更改申请对象数量
②内存资源耗尽未释放
找到未释放的对象进行释放
③本身资源不够
jmap -head 查看堆信息
4.1如何通过dump定位?
①系统已经OOM挂了
提前设置-XX:+HeapDumpOnOutOfMemory -XX:HeapDumpPath=./xxx
②系统运行还未OOM
导出dump文件:jmap -dump:format=b,file=xx.hprof 14660
或者Arthas 进行监测
③结合Jvisualvm进行调试
查看最多跟业务有关对象-->找到GcRoot--->查看线程栈
5.一个对象从加载到JVM,再到被GC清除,都经历了什么过程 ?
①用户创建一个对象,JVM首先需要到方法区去找对象的类型信息,然后再创建对象。
②JVM 要实例化一个对象,首先要在堆当中创建一个对象--->半初始化状态
③对象首先会分配在堆内存中新生代的eden区,然后经历一次minorGc,如果存活就进入S区,在后续中一直存活,会在S区进行拷贝,每移动一次,分代年龄加一,分代年龄到15后,下次就会进入老年代
④当方法执行结束后,栈中的指针会先移除掉。
⑤堆中的对象,经过mixedGc/FullGc ,就会被GC线程清理掉
6.Java线程锁机制是怎样的?偏向锁,轻量级锁,重量级锁有什么区别?锁机制是如何升级的?
① Java的锁就是在对象的markWord中记录的一个锁状态,无锁,偏向锁,轻量级锁,重量级锁对应不同的锁状态。
②Java的锁机制是根据资源竞争的激烈程度不断进行锁升级的过程
new对象 --->普通对象--->偏向锁--->轻量级锁--->重量级锁(偏向锁未启动->一个线程-->轻度竞争--->重度竞争)
new对象 --->普通对象--->偏向锁--->重量级锁 (偏向锁未启动->一个线程-->重度竞争)
new对象 --->普通对象--->轻量级锁--->重量级锁 (偏向锁未启动->偏向锁未启动-->重度竞争)
new对象 --->匿名偏向---->偏向锁-->轻量级锁--->重量级锁(偏向锁已启动->一个线程-->轻度竞争-->重度竞争)
new对象 --->匿名偏向---->偏向锁-->重量级锁(偏向锁已启动->一个线程-->重度竞争)
③总结:Java锁机制的升级时JVM对锁竞争程度的动态适配
无锁--->偏向锁:单线程场景,消除锁开销
偏向锁--->轻量级锁:轻微竞争,用CAS和自旋优化
轻量级锁--->重量级锁:激烈竞争,依赖操作系统阻塞机制
7.谈一谈,你对AQS的理解,AQS如何实现可重入锁?
Ⅰ.AQS是Java线程同步的框架,是jdk中很多锁工具的核心实现框架。
Ⅱ. 在AQS中维护了一个信号量state和一个线程组成的双向链表队列。其中这个队列就是给线程排队的而state就像一个红绿灯,用来控制线程排队或者放行的。在不同的场景下,有不同的意义。
Ⅲ。在可重入的场景下,state就是用来表示加锁的次数,0表示为无锁,每加一次锁,state就加一,释放锁,state就减一。