最近使用mvel 2.2.0.Final,出现一次cpu跑满,经过线程栈分析,发现是误用WeakHashMap引起的。

故障现场:

看WeakHashMap源码:

    public V get(Object key) {
Object k = maskNull(key);
int h = hash(k);
Entry<K,V>[] tab = getTable();
int index = indexFor(h, tab.length);
Entry<K,V> e = tab[index];
while (e != null) {
if (e.hash == h && eq(k, e.get()))
return e.value;
e = e.next;
}
return null;
}

线程在WeakHashMap的get方法里面出不来了,一直在while循环里面。

多线程并发get和put,fullgc或gc的时候可能会出现。
因为gc会把对象给清理掉,然后get方法内的while循环一直找不到eq的对象,循环出不来。

WeakHashMap类已经说明了这个类不是线程安全的。在[2.1.8.Final,~]以上修复了,除了2.2.0.Final,修复详情

问题复现:

import java.util.Map;
import java.util.Random;
import java.util.WeakHashMap; public class WeakHashMapTest { Thread thread = new Thread(new Runnable() { @Override
public void run() {
}
}); public static void main(String[] args) throws InterruptedException {
Random random = new Random();
// Map<String, String> weak = Collections.synchronizedMap(new WeakHashMap<>());//OK
Map<String, String> weak = new WeakHashMap<>();
for (int i = 0; i < 10; i++) {
weak.put(new String("" + i), "" + i);
}
for (int i = 0; i < 20; i++) {
new Thread(new Runnable() { @Override
public void run() {
StringBuffer sb = new StringBuffer();
for (int k = 0; k < 200; k++) {
sb.append(weak.get(new String("" + (k) % 10)));
if (k % 17 == 0) {
System.gc();
}
int nextInt = random.nextInt(10);
weak.put(new String("" + nextInt), "" + nextInt);
}
System.out.println("end:" + sb.toString());
}
}).start();
}
System.gc();
System.out.println("sleep");
Thread.sleep(10000);
System.out.println("exit");
System.out.println("exit2");
} static void test1() {
Map<String, String> weak = new WeakHashMap<>();
weak.put(new String("1"), "1");
weak.put(new String("2"), "2");
weak.put(new String("3"), "3");
weak.put(new String("4"), "4");
weak.put(new String("5"), "5");
weak.put(new String("6"), "6");
System.out.println(weak.size());
System.gc(); //手动触发 Full GC
try {
Thread.sleep(50); //我的测试中发现必须sleep一下才能看到不一样的结果
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(weak.size());
} }

误用WeakHashMap引起的死循环cpu跑满问题的更多相关文章

  1. syslog-ng-3.5.6把容器的单核cpu跑满

    Question 最近,偶然,会有人说,其docker容器中syslog-ng把cpu跑满,使用perf,mpstat,strace工具看到是syslog-ng在内核态cpu使用率很高,怀疑是某个系统 ...

  2. 云计算之路-阿里云上: RDS实例CPU跑满引发的故障

    今天上午 10: 40 左右,我们所使用的阿里云 RDS 实例的 CPU 突然飙高到近 100% ,造成大量数据库查询操作缓慢.超时,在这个恶劣条件下大量 memcached 缓存无法建立,这样的雪上 ...

  3. 追踪CPU跑满 堆栈调试

    http://blog.donghao.org/2014/04/24/%E8%BF%BD%E8%B8%AAcpu%E8%B7%91%E6%BB%A1/

  4. 回某位朋友问题备受phpcgi.exe煎熬现在cpu跑满(解决方案)

    (本文原创,但是cgi参数参考一个大神写的针对小服务器的,希望大家积极投票哦) 下面是对php-cgi.ext过多引起服务器cup%的解决方法,希望对大家有帮助;大多数情况是发生在第四项上;   解决 ...

  5. 追踪CPU跑满

    http://blog.donghao.org/2014/04/24/%e8%bf%bd%e8%b8%aacpu%e8%b7%91%e6%bb%a1/

  6. 记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)

    项目上线以来一直存在一个比较揪心的问题,和一个没有信心处理的BUG,那就是在应用程序启动时有可能会导致cpu跑满99%或持续在一个值如50%左右,这样一来对服务器的压力是非常大的,经常出现服务器无法远 ...

  7. 把 CPU “玩”起来

    前言 从开始学习编程之后,就渐渐痴迷于技术,平时遇到购书满减活动时就忍不住买一堆书.前两天闲着无聊,翻开了去年买的<编程之美>,目录里的“让 CPU 占用率听你指挥”吸引力我的眼球.这一年 ...

  8. 云计算之路-阿里云上:2014年6月12日14:40出现CPU 100%

    这是今天遇到的第2次故障,主站1台云服务器在14:40:33-14:41:09期间出现CPU突然跑满的状况,而CPU跑满之前,请求量并没有明显增长. 向阿里云提交之后,说晚上会对这台云服务器的虚拟机进 ...

  9. [转]如何根据cpu的processor数来确定程序的并发线程数量

    原文:http://blog.csdn.net/kirayuan/article/details/6321967 我们可以在cat 里面发现processor数量,这里的processor可以理解为逻 ...

随机推荐

  1. 数据库备份和还原(固定IP版)

    使用方法: 1.首次使用双击export.bat进行备份数据库:2.以后每次使用双击setup.bat进行还原数据库: 备注:如果数据库内容有变,需要重新执行export.bat进行备份数据库. ex ...

  2. pta总结2

    7-1 币值转换 (20 分) 输入一个整数(位数不超过9位)代表一个人民币值(单位为元),请转换成财务要求的大写中文格式.如23108元,转换后变成"贰万叁仟壹百零捌"元.为了简 ...

  3. JavaScript我学之一变量类型

    本文是网易云课堂金旭亮老师的课程笔记,记录下来,以供备忘. 变量类型  只有6种 : 四种原始数据类型boolean , number, string , undefine, 其他object,fun ...

  4. Spring Boot mybatis HashMap +layui 通用分页

    背景: mybatis 常用数据查询的方法都是先建实体类,再建Mapper,最后写Service,如果只是单纯的去查询数据显示,这样操作太麻烦.本文就以mybatis +layui创建通用分页类,简化 ...

  5. lxml.etree.HTML(text) 解析HTML文档

    0.参考 http://lxml.de/tutorial.html#the-xml-function There is also a corresponding function HTML() for ...

  6. asp+SqlServer2008开发【第一集:安装SqlServer2008以及登陆】

    参考:https://blog.csdn.net/i_likechard/article/details/75299983 1,安装sqlServer2008的具体步骤参考网上其他教程,自己根据注释引 ...

  7. 项目之初的模型设计与status状态字段

    0X01 开始做一个app的时候,要先做的是流程设计与数据库模型设计. 但做的模型设计往往是设置字段满足当前的需求,缺乏足够的经验,即使为以后的功能预留出位置,也无法考虑周全. 比如,刚开始做用户表, ...

  8. windows控件理论学习

    mmp快考试了还在浪 一.对话框编辑器创建控件 1.使用new在堆上创建,系统结束时我们需要使用delete去销毁控件 2.对话框编辑器控件,程序结束,自动销毁 二.控件类的基类 CWnd类和消息映射 ...

  9. Python中何时使用断言

    这个问题是如何在一些场景下使用断言表达式,通常会有人误用它,所以我决定写一篇文章来说明何时使用断言,什么时候不用. 为那些还不清楚它的人,Python的assert是用来检查一个条件,如果它为真,就不 ...

  10. vscode插件安装失败的解决方案

    在vscode中点击对应插件的install按钮安装,安装失败,软件提示手动安装(manually install). 手动下载vsix安装包,然后点击install from VSIX...,选择v ...