踩坑了,JDK8中HashMap依然会死循环!
是否你听说过JDK8之后HashMap已经解决的扩容死循环的问题,虽然HashMap依然说线程不安全,但是不会造成服务器load飙升的问题。
然而事实并非如此。少年可曾了解一种红黑树成环的场景,=v=
今日在查看监控时候发现,某一台机器load飙升

感觉问题不对劲,ssh大法登陆机器,top,top -Hp,jstack,jmap四连击保存下来堆栈,cpu使用最高的线程,内存信息准备分析。
首先查看使用最耗费cpu的线程堆栈信息
cat stack | grep -i 34670 -C10 --color

我勒个去,HashMap,猜测八成死循环了,但是我们使用的JDK8,在8中通过栈封闭的链表替换,解决了扩容死循环的问题。疑惑,继续往下看。
根据堆栈信息,root方法是问题所在,点开HashMap源码

好嘛,load飙高,代码有个for语句,我觉得铁定死循环了,看代码情况只可能是两个红黑树节点的父亲节点相互引用才可以导致无法走出这个for语句。
然而这都是我的猜测,我没有证据。而且让我追红黑树的代码,也是需要耗费大量时间的事情,我需要快速验证我的猜测。
我之前dump下来了堆内存信息,我通过jhat 命令生成html的内存信息页面

然后输入http://localhost:7000查看
我先找业务代码中持有这个HashMap的对象,然后点进去查询内部信息

因为数据都放在table中,点击Table字段,查看其内容
table中存在唯一的一个TreeNode节点,这肯定是已经变成了红黑树了
点进去查看

点击parent字段信息

0x72745d828与0x72745d7b8两个TreeNode节点的Parent引用都是对方。
后续打算深入研究一下红黑树什么场景会造成这个原因。
最后,无论什么并发场景请别使用HashMap,ConcurrentHashmap大法好
踩坑了,JDK8中HashMap依然会死循环!的更多相关文章
- JDK7与JDK8中HashMap的实现
JDK7中的HashMap HashMap底层维护一个数组,数组中的每一项都是一个Entry transient Entry<K,V>[] table; 我们向 HashMap 中所放置的 ...
- 深入分析 JDK8 中 HashMap 的原理、实现和优化
HashMap 可以说是使用频率最高的处理键值映射的数据结构,它不保证插入顺序,允许插入 null 的键和值.本文采用 JDK8 中的源码,深入分析 HashMap 的原理.实现和优化.首发于微信公众 ...
- jdk7中hashmap实现原理和jdk8中hashmap的改进方法总结
1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1 ...
- JDK8中HashMap
引用别人的一句话: JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多 ...
- [踩坑系列]URLEncode 中对 空格的编码有 “+”和“%20”两种
URL中的空格有时候被编码成%20,有时候被编码成加号+,曾经迷糊过一段时间,后来查了下资料才搞明白. 一个URL的基本组成部分包括协议(scheme),域名,端口号,路径和查询字符串(路径参数和锚点 ...
- Android踩坑随笔Fragment中onActivityResult方法不被调用
最近项目里要做头像功能,参考了这篇博客(GitHub - zhudfly/SelectAvatarApplication: 一个选择并显示头像圆形控件,可以通过拍照或者选择相册中的图片来设置图片),但 ...
- 【数据结构】27、红黑树,节点插入,修复平衡操作总结(针对jdk8中hashmap冲突过多链表转红黑树)
二叉树节点插入 0.如果只有一个节点,那么就直接作为根,涂黑,如果父为黑,或者祖父为空,那么不做操作 1.叔叔节点不为空且为红 那么就修改父,叔叔,祖父节点颜色,最后把当前节点设置为祖父节点,在进行平 ...
- HashMap在JDK7和JDK8中的区别
在[深入浅出集合Map]中,已讲述了HashMap在jdk7中实现,在此就不再细说了 JDK7中的HashMap 基于链表+数组实现,底层维护一个Entry数组 Entry<K,V>[] ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
随机推荐
- C、C++、Java、Python该怎么选
对于很多对编程感兴趣的小伙.或是正在读计算机专业的大学生来说,不知道要选择哪一门编程语言发展.对于计算机专业的学生,一般的学习都普遍会开始设C.C++.Java等热门的编程语言,但还是不太清楚选择哪一 ...
- 【期外】(二)还是N皇后动画演示
题目:n皇后题目 题解:n皇后题解 演示:
- 使用Java API进行tar.gz文件及文件夹压缩解压缩
在java(JDK)中我们可以使用ZipOutputStream去创建zip压缩文件,(参考我之前写的文章 使用java API进行zip递归压缩文件夹以及解压 ),也可以使用GZIPOutputSt ...
- 准确率99.9%的离线IP地址定位库
Ip2region是什么? ip2region - 准确率99.9%的离线IP地址定位库,0.0x毫秒级查询,ip2region.db数据库只有数MB,提供了java,php,c,python,nod ...
- vue 父子之间传值
1:父组件 子组件 子组件利用 props 接收父级传过来的数值.子组件选中的数值返回父亲当中利用 钩子函数 $emit('函数名',传过去的数值)
- manjaro与python开发环境配置
1.manjaro配置 1.1.启动项 sudo update-grub 注:Manjaro(archLinux)系统时间快8小时--> sudo timedatectl set-local-r ...
- 详解Apache Hudi如何配置各种类型分区
1. 引入 Apache Hudi支持多种分区方式数据集,如多级分区.单分区.时间日期分区.无分区数据集等,用户可根据实际需求选择合适的分区方式,下面来详细了解Hudi如何配置何种类型分区. 2. 分 ...
- git存储用户名和密码
git config --global credential.helper store 输入一次用户名和密码后,git会自动记录用户名密码
- MPI聚合函数
MPI聚合通信 MPI_Barrier int MPI_Barrier( MPI_Comm comm ); 所有在该通道的函数都执行完后,才开始其他步骤. 0进程在状态T1调用MPI_Barrier函 ...
- 模型层中QuerySet的学习
创建对象 使用关键字参数实例化模型实例来创建一个对象,然后调用save()把它保存到数据库中 pub_obj = models.Publisher(title='奥利给出版社') pub_obj.sa ...