高并发中的卡死状态 -HashMap

12 九月, 2010 (17:40) | Testing, 性能 繁体 English    DeliciOus    分享到新浪微博
作者: H.E. | 您可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
网址: http://www.javabloger.com/article/concurrenthashmap-stuck-in-java-high-concurrency.html
豆瓣读书 向你推荐有关 Testing性能、 类别的图书。

场景
http servlet 异步请求原先是30秒,现在挂起的时间设置为0,进来就出去,没有等待时间,
     场景一:发起30000个挂起请求,中间间隔5秒钟, 测试中CPU 使用率 75%,测试完毕CPU使用率 60%-75%  ,open/active connections  当前活动数量 12000,这个是不正常的
       
    场景二:发起12000-15000个挂起请求, 中间间隔10秒钟,测试中CPU 使用率 75%,测试完毕CPU使用率 0%-1% 和 open/active connections 参数一切正常
       
    场景三:发起12000-15000个挂起请求, 中间间隔2秒钟,测试中CPU 使用率 75%,测试完毕CPU使用率 60%-75% 和 open/active connections 当前活动数量 5000多个,这个也是不正常的
    
    场景四: 把GlassFish中的现在的应用程序去掉,写一个非常简单的http请求,再做 30000个并发请求,同样的环境中没有任何问题发生,此时一切正常,唯一不同的就是程序不同,可以90%的将问题定位到我们自己的程序上了。
    
上述open/active connections是指用查看GlassFish 中活动的当前 http活动连接数  可以使用命令进行查看当前的http上连接的活动状态
asadmin get –monitor=true "server.network.http-listener-1.*" |grep countopenconnections-count

如图所示:

http://1aqpcg.bay.livefilestore.com/y1pV2RYRTioNPAWZGT3GlJiw_oBC4_hpmoRvbSwvTI450bnF-N4yys47c-MnVKhpT56vyb8RC8OycH67DVK0_tJF9SCI4VKzctA/close_wait3_02a-15960.jpg?psid=1

查看大图请点击这里

通过上述的测试过程,我们还可以发现一个不同的地方,那就是对现有的应用程序发起请求是不是并发请求,例如 上述的场景二和场景三,如果是并发请求,必死无疑,但是 如果还是一样的并发数量但是请求的间隔时间长了,例如30000个请求中间发起间隔10秒说明不是并发请求。Ok,问题到这一步,可以确定是我们的程序能否能支持大量并发的问题了。

经过反复检查代码以后发现原来是程序中使用 HashMap 的问题,换成 ConcurrentHashMap 来代替 HashMap 后一切又正常了,因为
HashMap并不是线程安全的,如果你的单例类没有做代码同步或对象锁的控制,而ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术,它使用了多个锁来控制对hash表的不同部分进行的修改。 ConcurrentHashMap内部使用Segment来表示这些不同的段落,每个段其实就是一个小的hash table。它使用了多个锁来控制对hash table 的不同部分进行的修改。而HashMap需要做到同步的机制时候 它通过提供一个不同步的基类和一个同步的包装器 Collections.synchronizedMap ,来解决线程安全性的问题。简单来说HashMap在同步的时候是锁全表,而 ConcurrentHashMap 在同步的时候是锁某一个段落。还记得 MySQL中的 MyISAM 和InnoDB吗?InnoDB是行锁类似ConcurrentHashMap,而MyISAM类似于HashMap是整个表锁,我只是打一个比方,为了便于自己记忆和理解。

注意:以上内容纯属虚构,不牵涉任何内部机密,如有雷同纯属巧合。

–end–

豆瓣读书  向你推荐有关 Testing 性能、 类别的图书。



Creative Commons License
本文由J2ee企业顾问-黄毅创作,并已采用创作共用署名2.5中国大陆版许可证授权。

评论

Comment from fabo wang
Time 2010年09月13日 at 12:53 下午

并行的地方用Hashmap会有死循环的问题,这跟hashmap的内部实现是有关系的。问题出在元素增长的时候hashmap重新分配的地方。如果一次给足够的空间存放。不会出现问题。
btw:hashmap昨为非线程安全的类,在多线程场景中是不适用的

Comment from windgogole
Time 2011年06月16日 at 4:29 下午

楼上正解,遇到过HashMap造成死循环的现象

评论

评论也是有版权的!




7213