lesson10:hashmap变慢原因分析
下面的英文描述了String.hashCode()方法,在特定情况下,返回值为0的问题:
Java offers the HashMap and Hashtable classes, which use the
String.hashCode() hash function. It is very similar to DJBX33A (instead of 33, it uses the
multiplication constant 31 and instead of the start value 5381 it uses 0). Thus it is also
vulnerable to an equivalent substring attack. When hashing a string, Java also caches the
hash value in the hash attribute, but only if the result is different from zero.
Thus, the target value zero is particularly interesting for an attacker as it prevents caching
and forces re-hashing.
接下来我们来看一下String类的hashCode()方法:当下面代码中的val[off++]返回值都是0的情况下,hashCode()的返回值也是0
public int hashCode() {
int h = hash;//初始值为0
if (h == 0 && count > 0) {//count值为字符个数
int off = offset;//off值为0
char val[] = value;//字符数组
int len = count; for (int i = 0; i < len; i++) {
h = 31*h + val[off++];//如果val[off++]的所有返回值都是ascii码0会发生什么?
}
hash = h;
}
return h;
}
我们知道hashmap存储值的数据结构是数组+链表的结果,如果不同的key值,但是返回的hashcode()值都是0的话,hashmap的结构不会得到很好的应用,会造成所有的元素都存储在数组的第一个元素的链表中,下面通过代码来证明:
package com.mantu.advance; import java.util.HashMap; public class Lesson10HashmapLeak { public static void main(String[] args){
testHashMapNormal();
testHashMapBug();
} public static void testHashMapBug(){
HashMap<String,String> map = new HashMap<String,String>(100000);
String xxx= asciiToString("0");
String temp = xxx;
long beginTime = System.currentTimeMillis();
//System.out.println("开始时间:"+System.currentTimeMillis());
for(int i=0;i<100000;i++){
map.put(xxx, i+""); if((i%10000)==0){
xxx=temp;
}
else{
xxx=xxx+temp;
}
}
System.out.println("testHashMapBug()耗时:"+(System.currentTimeMillis()-beginTime)+"毫秒");
} public static void testHashMapNormal(){
HashMap<String,String> map = new HashMap<String,String>(100000);
String xxx= asciiToString("1");
String temp = xxx;
long beginTime = System.currentTimeMillis();
//System.out.println("开始时间:"+System.currentTimeMillis());
for(int i=0;i<100000;i++){
map.put(xxx, i+""); if((i%10000)==0){
xxx=temp;
}
else{
xxx=xxx+temp;
}
}
System.out.println("testHashMapNormal()耗时:"+(System.currentTimeMillis()-beginTime)+"毫秒");
}
public static String asciiToString(String value)
{
StringBuffer sbu = new StringBuffer();
String[] chars = value.split(",");
for (int i = 0; i < chars.length; i++) {
sbu.append((char) Integer.parseInt(chars[i]));
}
return sbu.toString();
}
}
最后的执行结果是:
正常key值的一组执行时间是:1887毫秒
key值对应的hashcode()值为0的执行时间是:7365毫秒
lesson10:hashmap变慢原因分析的更多相关文章
- SELECT TOP 1 比不加TOP 1 慢的原因分析以及SELECT TOP 1语句执行计划预估原理
本文出处:http://www.cnblogs.com/wy123/p/6082338.html 现实中遇到过到这么一种情况: 在某些特殊场景下:进行查询的时候,加了TOP 1比不加TOP 1要慢(而 ...
- HashMap多线程并发问题分析
转载: HashMap多线程并发问题分析 并发问题的症状 多线程put后可能导致get死循环 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题. ...
- Beforeunload打点丢失原因分析及解决方案
淘宝的鱼相在 2012 年 8 月份发表了一篇文章,里面讲述了他们通过一个月的数据采集试验,得到的结果是:如果在浏览器的本页面刷新之前发送打点请求,各浏览器都有不同程度的点击丢失情况,具体点击丢失率统 ...
- SQL Server 磁盘请求超时的833错误原因分析以及解决
本文出处:http://www.cnblogs.com/wy123/p/6984885.html 最近遇到一个SQL Server服务器响应极度缓慢,并且出现客户端请求报错的情况,在数据库中的erro ...
- SQL查询速度慢的原因分析和解决方案
SQL查询速度慢的原因分析和解决方案 查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建 ...
- PHPWAMP自启异常,服务器重启后Apache等服务不会自动重启的原因分析
在使用“PHPWAMP自动任务”时,不少学生遇到如下问题: “phpwamp绿色集成环境重启动电脑(服务器)后,不会自动启动网站服务” (如果是其他环境或是自己搭建时遇到此问题,也是可以用此法解决) ...
- sql 查询慢的48个原因分析
sql 查询慢的48个原因分析. server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半). 字句同时执行,SQL SERVER根据系统的负载情况决定最优的 ...
- ORACLE中order by造成分页不正确原因分析
工作中遇到的问题: 为调用方提供一个分页接口时,调用方一直反应有部分数据取不到,且取到的数据有重复的内容,于是我按以下步骤排查了下错误. 1.检查分页页码生成规则是否正确. 2.检查SQL语句是否正 ...
- Android ListView异步载入图片乱序问题,原因分析及解决方式
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android全部系统自带的控件其中,ListView这个控件算是 ...
随机推荐
- 最新xgboost python32位下安装xgboost
网上很多windows python下安装xgboost都是很简单的几步无非是visual studio2013以上版本编译,安装.但现在最新的xgboost已经移除了c++工程文件,找到旧版本的也多 ...
- c++primerplus(第六版)编程题——第5章(循环和关系表达式)
声明:作者为了调试方便,每一章的程序写在一个工程文件中,每一道编程练习题新建一个独立文件,在主函数中调用,我建议同我一样的初学者可以采用这种方式,调试起来会比较方便. (具体方式参见第3章模板) 1. ...
- ubuntn 虚拟机NAT 静态IP 网络配置
在虚拟机安装ubuntu12.04自动获取IP 一切都没有问题 ssh连接也正常.关机重启后郁闷的发现网络已经不通了,于是开始了以下的摸索. 1.配置静态IP 网关: ip段: 命令: Vim /et ...
- JQuery 绑定回车事件 兼容ie8,ie9
$("#form-search").find('#search-query').bind('keypress', function(e) { var keycode; if(win ...
- Linux下ln链接命令详解
ln是linux中又一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个不同的链接,这个命令最常用的参数是-s,具体用法是:ln –s 源文件 目标文件. 当我们需要在不同的目录,用到相同的 ...
- Bootstrap_表单_表单样式
一.基础表单 <form > <div class="form-group"> <label>邮箱:</label> <inp ...
- php如何计算两个时间戳之间相差的日时分秒
/功能:计算两个时间戳之间相差的日时分秒//$begin_time 开始时间戳//$end_time 结束时间戳function timediff($begin_time,$end_time){ if ...
- JQuery解析HTML、JSON和XML实例详解
1.HTML 有的时候会将一段HTML片段保存在HTML文件中,在另外的主页面直接读取该HTML文件,然后解析里面的HTML代码片段融入到主页面中. fragment.html文件,其内容: 复制代码 ...
- nodebb在阿里云主机部署过程
1.在centos上安装nodejswget http://nodejs.org/dist/v0.8.9/node-v0.8.9.tar.gztar zxvf node-v0.8.9.tar.gzcd ...
- objective-c 错题
//1, NSString *name = [[NSString alloc]initWithString:@"张三"]; NSLog(@"%d",[name ...