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这个控件算是 ...
随机推荐
- 关于JavaScript的类的继承
其实最一开始学JS的时候就看过继承的实现.当时只是去试着理解从书上看来的代码段而已.今天又重新思考了一下,感觉这是一个思维探索演进的结果. 继承,即复用. 如果抛开继承的固有思想,让b复用a的成员,最 ...
- PSD 转化成 HTML
一般情况下,网页设计制作完成的工作实际是:psd 效果图 转成 html+CSS 的模板页面,一般情况下,我们会拿到美工的 psd,不同的人会有不同的做法: 打开fireworks将图片切割导出为ht ...
- Fedora 21 安装VirtualBox
注: 所有操作需要root权限 如果不是root用户在下面所有命令前加sudo 装dkms,kernel-devel,makecache: yum install dkms yum install ...
- Canvas实现文字粒子化,并且绕轴旋转(初号机)
写下来发现,程序在细节上处理的很差,比如旋转的时候,在终点处有明显的撞墙感觉,以及小部分粒子存在精度差异,导致撞击后不与整体平衡. 注释全在代码中了,就不多说了,另外感觉写的旋转的规则有点怪,后续再调 ...
- JavaScript 获取Select标签选中的项
<select name="select1" id="select1" onchange=setInput()> <option value= ...
- android开发学习笔记:圆角的Button
转自:http://www.cnblogs.com/gzggyy/archive/2013/05/17/3083218.html 在res目录下的drawable-mdpi建立xml文件shape.x ...
- SQL Server 2008无日志文件附加数据库
1.新建一个同名数据库. 2.停止数据库服务,覆盖新建的数据库主文件(小技巧:最好放在同一个磁盘里面,把新建的数据库主文件删掉或移开,再把要恢复的数据库主文件剪切过去,这样就可以节省时间.) 3.启动 ...
- Scut AccountServer
开始以Scut搭建服务器框架: 1. 初始目录结构: libs 存放 scut 的引擎文件: release 存放 src 输出的文件: src 存放各子工程源文件: 2. Install.bat:目 ...
- Node.js缓冲器
纯JavaScript是Unicode友好的,但对二进制数据不是很好.当与TCP流或文件系统打交道时,有必要处理字节流. Node提供缓冲器类,它提供实例来存储原始数据相似的一个整数数组,但对应于在V ...
- js 实现 di
前些时候有使用过AngularJS一些时间,最大的感受就是Angular完全颠覆了我们开发Web应用的方式,自己被其许多耳目一新的设计思想所折服. 首先想说的就是依赖注入(DI),这也意味着,你在使用 ...