Java内存泄漏、性能优化、宕机死锁的N种姿势( 六 )


Java内存泄漏、性能优化、宕机死锁的N种姿势

文章插图
 

Java内存泄漏、性能优化、宕机死锁的N种姿势

文章插图
 
封装不严谨导致的死锁jstack打出的死锁信息如下所示 。grpc-default-executor-3449线程拿到了RaftLog的锁 , 在等DataBlockingQueue的锁;SegmentedRaftLogWorker拿到了DataBlockingQueue的锁 , 在等RaftLog的锁 。
Java内存泄漏、性能优化、宕机死锁的N种姿势

文章插图
 

Java内存泄漏、性能优化、宕机死锁的N种姿势

文章插图
 
这里最值得怀疑的是SegmentedRaftLogWorker拿到了DataBlockingQueue的锁却不释放 , 因为queue的操作只是在队列里增、删、查元素 。如下图所示DataBlockingQueue的方法poll , 使用的锁是自己封装的锁AutoCloseableLock implement AutoCloseable,锁的释放依赖于AutoCloseableLock重载的close方法 。
Java内存泄漏、性能优化、宕机死锁的N种姿势

文章插图
 
再看acquire方法 , 先用lock.lock()拿到锁 , 再创建新的AutoCloseableLock对象 , 如果拿到锁后 , 在创建新对象AutoCloseableLock时发生OOM等异常 , 锁就无法释放 。
Java内存泄漏、性能优化、宕机死锁的N种姿势

文章插图
 
参考
[1]https://www.waitingforcode.com/Apache-spark/apache-spark-off-heap-memory/read
[2]https://github.com/alibaba/arthas/releases/tag/arthas-all-3.3.6
[3]https://www.jaegertracing.io/docs/1.18/getting-started/
[4]https://stackoverflow.com/questions/3537870/production-settings-file-for-log4j/




推荐阅读