最近使用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. 在Windows环境下搭建Nginx文件服务器(简单实用版)

    为了解决项目组内容应用,打算把本地的e:tools目录共享出来,具体操作步骤如下1.下载安装包:http://nginx.org/download/nginx-1.9.15.zip2.解压缩3.修改配 ...

  2. 2018秋季C语言学习总结

    2018秋季开始学习c语言 1.printf格式化输出函数 2.基本数据类型,int整型,float浮点型,double双精度浮点型,char字符型 3.算数运算符 +加法,-减法,*乘法,/除法,% ...

  3. spring Boot异步操作报错误: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.self.spring.springboot.Jeep' available

    我也是最近开始学习Spring Boot,在执行异步操作的时候总是汇报如下的错误: Exception in thread "main" org.springframework.b ...

  4. [转] 如何写好.babelrc?Babel的presets和plugins配置解析

    什么是Babel The compiler for writing next generation JavaScript. 官网是这么说的,翻译一下就是下一代JavaScript 语法的编译器. 作为 ...

  5. 继承了AppCompatActivity的全屏设置

    v7下全屏设置:getSupportActionBar().hide();getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ...

  6. JS语法转换-ES6转ES5

    1.使用Babel转码 全局安装 npm install -g babel-cli 布局安装 npm install -g babel-cli --save-dev Babel的配置文件是.babel ...

  7. Python开发技术详解PDF

    Python开发技术详解(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1F5J9mFfHKgwhkC5KuPd0Pw 提取码:xxy3 复制这段内容后打开百度网盘手 ...

  8. opencv coudn't find video stream from "XXX(文件名)"

    opencv coudn't find video stream from "XXX(文件名)" 我用的是clion 解决方法: 把路径设为完整路径,如"C:/XXX&q ...

  9. MongDB 数据结构

    Object  ID :Documents 自生成的 _id String: 字符串,必须是utf-8 Boolean:布尔值,true 或者false (这里有坑哦~在我们大Python中 True ...

  10. bat入门--第一个bat文件

    所谓的批处理就是从记事本开始进行的. 1.新建一个记事本文件, 2, 打开的记事本上敲入一行字:@echo off 意思:隐藏以下输入的代码(off改成on是打开代码显示). 3.再输入:echo h ...