JVM 内存溢出和死锁检测

内存溢出案例

案例环境

案例代码

bash 复制代码
package com.hero.jvm.memory;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class TestJvmOutOfMemory {
  public static void main(String[] args) {
    List<Object> list = new ArrayList<>();
    for (int i = 0; i < 10000000; i++) {
      String str = "";
      for (int j = 0; j < 1000; j++) {
        str += UUID.randomUUID().toString();
     }
      list.add(str);
   }
    System.out.println("ok");
 }
}

JVM 参数

  1. 让案例尽快 OOM
  2. 开启发生 OOM 时自动 dump 堆快照
bash 复制代码
#参数如下:
-Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError

执行结果

溢出打印

bash 复制代码
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid31092.hprof ...
Heap dump file created [8453096 bytes in 0.031 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at com.hero.TestJvmOutOfMemory.main(TestJvmOutOfMemory.java:13)

dump 了堆快照文件

导入 MAT 分析

可以看到,有81.72%的内存由Object[]数组占有,所以比较可疑。

分析:这个可疑是正确的,因为已经有超过80%的内存都被它占有,这是非常有可能出现内存溢出的。

直接看对象详情

死锁检测

如果在生产环境发生了死锁,我们将看到的是部署的程序没有任何反应了,这个时候我们可以借助jstack进行分析,下面我们实战下查找死锁的原因。

案例环境

java 复制代码
public class TestDeadLock {
    private static Object obj1 = new Object();
    private static Object obj2 = new Object();
    public static void main(String[] args) {
        new Thread(new Thread1()).start();//启动线程01
        new Thread(new Thread2()).start();//启动线程02
    }
    //线程01
    private static class Thread1 implements Runnable {
        @Override
        public void run() {
            synchronized (obj1) {
                System.out.println("Thread1 拿到了 obj1 的锁!");
                try {
                    // 停顿2秒的意义在于,让Thread2线程拿到obj2的锁
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();

                }
                synchronized (obj2) {
                    System.out.println("Thread1 拿到了 obj2 的锁!");
                }
            }
        }
    }
    //线程02
    private static class Thread2 implements Runnable {
        @Override
        public void run() {
            synchronized (obj2) {
                System.out.println("Thread2 拿到了 obj2 的锁!");
                try {
                    // 停顿2秒的意义在于,让Thread1线程拿到obj1的锁
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj1) {
                    System.out.println("Thread2 拿到了 obj1 的锁!");
                }
            }
        }
    }
}

使用 Jstack 分析

命令:jstack 18487 | grep 'BLOCKED' -A 15 --color

发现两个互相等待锁的线程

使用 Arthas 分析死锁

thread-b 命令

相关推荐
2301_8092047016 分钟前
mysql在docker容器中如何部署_利用docker-compose快速启动
jvm·数据库·python
2301_815901974 小时前
SQL如何将多行记录聚合成逗号分隔字符串_GROUP_CONCAT技巧
jvm·数据库·python
zjy277775 小时前
Layui tab选项卡如何动态根据ID值进行程序化切换
jvm·数据库·python
m0_602857765 小时前
Redis如何修复槽位分配重叠的脏状态_使用redis-cli --cluster fix工具扫描并修复不一致的Slot
jvm·数据库·python
2301_766283445 小时前
怎样开启phpMyAdmin的操作审计日志_记录每条执行的SQL
jvm·数据库·python
zhoutongsheng6 小时前
如何解决ORA-01078参数文件错误_pfile与spfile互相创建恢复
jvm·数据库·python
2401_824222696 小时前
HTML怎么标注字数限制提示_HTML实时字数统计占位【详解】
jvm·数据库·python
littleM7 小时前
深度拆解 HermesAgent(五):记忆系统与用户建模
jvm·人工智能·架构·ai编程
dfdfadffa7 小时前
如何创建仅在首次订阅时执行一次计算的 RxJS 懒加载 Observable
jvm·数据库·python
m0_624578597 小时前
SQL分组后如何计算移动平均值_利用窗口函数AVG配合ROWS
jvm·数据库·python