前言
说到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…之后碰到还可以再补充
知易行难,“实践是检验真理的唯一标准”!