记一次简单OOM分析

Posted by New Boy on January 8, 2018

前言

说到OOM,out of memory也是一个广泛存在的问题,如果线上出了问题,临时抱佛脚肯定是不行的,所以未雨绸缪是必须的。

测试过程

首先是程序的准备

准备了两个OOM的程序


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author: dingmingcheng
 * @Description
 * @Date: Created in 下午8:15 2018/1/8
 * @Modifyed By:
 */
public class test {
    static class task implements Runnable{

        Long key;
        Long value;

        task(Long key, Long value) {
            this.key = key;
            this.value = value;
        }
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        ExecutorService threads = Executors.newFixedThreadPool(10);
        while (true) {
            threads.execute(new task(100L, 100L));
        }
    }
}

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.*;

/**
 * @Author: dingmingcheng
 * @Description
 * @Date: Created in 下午8:15 2018/1/8
 * @Modifyed By:
 */
public class test2 {
    public static void main(String[] args) {
        List<Long> list = new ArrayList<Long>();
        while(true) {
            Long it = new Long(123L);
            list.add(it);
        }
    }
}

具体实现过程

#编译这两个文件
javac test
javac test2
#运行,设置堆内存大小,方便观察结果
java -Xmx20m test 
java -Xmx5m test2 
#查看进程Id
jps

在之前的两个程序分别出现以下的情况

第一个程序

第二个程序

使用jmap生产dump文件并且进行分析:

#通过·jmap根据pid生成dump文件
jmap -dump:live,format=b,file=heap.hprof [pid]
#通过内置的jhat指令进行分析
jhat heap.hprof

结果查看地址:localhost:7000/

ecplise中有自带的MAT分析工具,应该会更加地直观,网上还是有很多关于它的使用的

知识发散

在进行测试时,发现OOM还是有很多种情况的,目前接触到这3种情况:

1.GC overhead limit exceede

大意是指98%的时间回收了不到2%的内存,jvm就认为这程序肯定会发生OOM,不再让它继续跑下去了,有兴趣也可以通过jstat命令去查看GC的情况,会出现大量的Full GC

2.Java heap space

超了设定的堆内存

3.unable to create new native thread

这问题时偶然碰见的,在程序一中,用newCachedThreadPool代替newFixedThreadPool就会出现,这其实和本机所允许的最大线程数有关,线程数超过了机子设定值时就会出现,通过ulimit -u也可以看见当前机子上的线程数量。

emmm…之后碰到还可以再补充

知易行难,“实践是检验真理的唯一标准”!