无语!JDK 8 中的 HashMap 依然会死循环…
发布日期:2021-06-30 12:55:16 浏览次数:2 分类:技术文章

本文共 1023 字,大约阅读时间需要 3 分钟。

Java技术栈

www.javastack.cn

关注阅读更多优质文章

是否你听说过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语句。

然而这都是我的猜测,我没有证据。而且让我追的代码,也是需要耗费大量时间的事情,我需要快速验证我的猜测。另外,面试想刷题的,可以在Java技术栈公号获取 Java 系列面试题,我都已经整理好了。

我之前dump下来了堆内存信息,我通过 命令生成html的内存信息页面:

然后输入http://localhost:7000查看

我先找业务代码中持有这个HashMap的对象,然后点进去查询内部信息

因为数据都放在table中,点击Table字段,查看其内容

table中存在唯一的一个TreeNode节点,这肯定是已经变成了了

点进去查看

点击parent字段信息

0x72745d828与0x72745d7b8两个TreeNode节点的Parent引用都是对方

后续打算深入研究一下红黑树什么场景会造成这个原因。

最后,无论什么并发场景请别使用HashMap,ConcurrentHashmap大法好。

作者:Aaron_涛

链接:https://blog.csdn.net/qq_33330687/article/details/101479385
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

关注Java技术栈看更多干货

戳原文,获取精选面试题!

转载地址:https://javastack.blog.csdn.net/article/details/111148278 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Oracle 要慌了!华为终于开源了自家的 Huawei JDK——毕昇 JDK!
下一篇:Java 生成随机数的 5 种方式,你知道几种?

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月30日 05时17分57秒