线程“无故”死亡,究竟谁是幕后黑手?
来源:互联网 发布:PHP删除数组中指定元素 编辑:程序博客网 时间:2024/04/28 15:46
今天,一上班,同事就火急火燎的跑过来问我:程序怎么不会跑数据了,是不是挂了?按照惯例得先问问同事是不是哪里没配置好,导致没数据产生,在确认不是数据问题的之后,就纳闷了:难道程序真的挂了。
那个程序是我开发的一个多线程程序,run方法是一个死循环,负责处理数据,合适的情况下线程会进行休眠,避免浪费cpu资源。我第一时间登上服务器,使用jps命令可以看到程序的进程好好的还在那。由于之前数据库连接池出现过问题,所以我首先怀疑是不是因为连接池出问题导致访问不了数据库。然而通过观察日志,并没发现连接池不够用。紧接着,我便怀疑起是不是线程产生死锁,导致不会跑数据。于是便使用
jstack pid命令查看堆栈,仔细的看了下里面的线程,发现并没有死锁,但是此时,通过观察堆栈,还是发现了些端倪:一开始我总共启动了20个线程,怎么现在只有那么寥寥几个。负责处理数据的那些线程全部壮烈牺牲。
是谁动了我的线程?
按理说运行这的线程如果出现问题,那么在程序日志里面肯定是能看到错误的,然而并没有!那究竟是谁动了我的线程。
第一个怀疑对象就是系统,但是仔细想想也不对,linux下面内存不够了,它直接开刀的是进程,但是我的进程依旧活的好好的,里面还有几个残留的线程在苟延残喘着,但是为了保险起见,我还是去看了下系统日志,发现并没有内存不足。
接下来,开始怀疑会不会是jvm搞的鬼。如果是程序使用内存高于启动参数设置的最大堆内存,会产生oom,jvm为了保证进程能活下来,会先把占内存的线程杀了。事情似乎渐渐明朗,由于启动程序的时候并没有设置 XX:+HeapDumpOnOutOfMemoryError ,所以即使发生oom,也会不产生dump文件。为了验证猜想,加入启动参数之后重新运行,果不其然,一段时间之后确实产生oom,使用jstack查看,堆栈里线程又剩下那么寥寥几个。此时大概可以断定,线程无缘无故死亡是因为oom导致线程被jvm杀了。通过用工具分析dump文件,发现无明显程序原因导致oom,所以应该是启动时分配的内存有点小。调大堆内存之后重新运行,不会再产生oom。
写了个模拟程序:
public class Main { //每个线程每次运行都申请10M内存 private static final int MEMORY = 1024*1024*10; private static CountDownLatch sum = new CountDownLatch(46);//限制使用的内存总数,确保可以看到部分存活线程 public static void main(String[] args) throws IOException { List<Object> objects = new ArrayList<>(); for (int i = 0; i < 10; i++) { new Thread(()->{ while (sum.getCount()>0) { objects.add(new byte[MEMORY]); sum.countDown(); try { Thread.sleep(3*1000); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } System.in.read(); }}
设置启动参数:
-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/dump
启动不久之后就能看到控制台输出 java.lang.OutOfMemoryError: Java heap space
之后用jstack查看,会发现10个线程剩下几个还存活着。
至此,问题来龙去脉已理清,也解决了问题。
- 线程“无故”死亡,究竟谁是幕后黑手?
- 食品价格上涨谁是幕后“黑手”?
- 中国房价一路狂涨 到底谁是幕后的黑手?
- 谁是手机天价流量费的幕后黑手
- 智能机销售达饱和 谁是幕后黑手?
- 对象存储来势汹汹,究竟谁是“幕后推手”?
- 支付宝呈现故障帐号钱没了 毕竟谁是幕后黑手
- 作为幕后黑手的IBM?
- 微软控告僵尸网络的幕后黑手
- 谁是“安史之乱”的幕后推手?
- UI更新为什么一定要在UI线程里?幕后真相究竟如何?
- PasswordRecovery无法正常支持中文的幕后黑手----ResponseEncoding
- 如何抓获JVM crash的幕后黑手?(一)
- 如何抓获JVM crash的幕后黑手?(二)
- 一个偷偷修改工作目录的幕后黑手
- 柯达出售专利受挫 称苹果是幕后黑手
- 如何抓获JVM crash的幕后黑手?(三)
- 谁是“西游记”事件的幕后指使人?
- strerror&gcc -W&__FILE__
- 【PAT】【Advanced Level】1083. List Grades (25)
- js的Number类型
- python 画柱状图折线图
- [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher(1) A-H
- 线程“无故”死亡,究竟谁是幕后黑手?
- 启动MongoDB提示报警信息:“WARNING: Access control is not enabled for the database.”
- 2017 ICPCECIC Birthday present
- linux硬链接与软链接
- JavaScript match()方法使用
- C++primer阅读笔记----------拷贝控制
- 普通链表
- Linux常用操作指令(面试专用)
- mysql insert into ..select 发生死锁问题。