Java HashMap 分析之四:查找和内存使用
2014-08-15 11:03
204 查看
获取元素
有了前面的分析,获取元素的逻辑就非常清晰。首先,调用者传递key,从key的hashCode方法获得值后,调用hash函数做一些低位置换,保证hash值的均匀分布,之后和size-1按位与后得到数组的位置。然后取出对应位置的链表,遍历该链表,查找hash值相等,并且key的引用或者值相等的对象,然后返回。代码见下面:[java]
view plaincopyprint?
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
public V get(Object key) { if (key == null) return getForNullKey(); int hash = hash(key.hashCode()); for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }
算法时间复杂度平均是O(1),如果hash code很糟糕,让其退化成链表,则是O(N).即便是O(1),也要注意,实际上计算hash用了好几步,绝对比直接从数组中获取某个元素的O(1)时间要长的多。
内存消耗
有一个很好的工具,可以帮助我们检查Java对象内存的消耗。从这里下载jar包:http://sizeof.sourceforge.net/解压后将SizeOf.jar复制到某个目录,比如我的/home/chenshu,在项目中加入这个jar包,并且设置JVM参数:-javaagent:/home/chenshu/SizeOf.jar。
这个类库提供了一些静态函数,利用java.lang.Instrument的Instrumentation.getObjectSize(),能够计算Java对象真正在虚拟机里面占用的内存大小。下面的代码创建了一个只保存一个对象的HashMap,并计算内存占用。
[java]
view plaincopyprint?
public static
void main(String[] args) {
// TODO code application logic here
HashMap<String,String> map = new HashMap<String,String>();
String put = map.put("a", "b");
String size = SizeOf.humanReadable(SizeOf.deepSizeOf(map));
System.out.println(size);
}
public static void main(String[] args) { // TODO code application logic here HashMap<String,String> map = new HashMap<String,String>(); String put = map.put("a", "b"); String size = SizeOf.humanReadable(SizeOf.deepSizeOf(map)); System.out.println(size); }结果是304字节,64bitJVM。真的很浪费内存,比我估计的要大多了!可见HashMap不是用来存放少量数据的。而且考虑到计算hash那么的复杂,如果只是喜欢Map这种Key,Value形式的接口,但并不保存较大数据量,应该考虑别的Map了。 Java其实提供了很多种Map,滥用HashMap的结果是只能开发“企业级“的应用,并且被我这种老程序员笑为富二代。:)
因此,在大数据量(个人认为超过1万),并且需要快速查找和插入的时候,HashMap是非常好的选择。但是如果数据量不大的情况下,以tree实现的Map也是一个不错的选择,毕竟节省很多内存。而且tree还可以实现set这样的数据结构,有时候比Map更符合我们的需求。
如果你现在拿起来就不假思索的使用HashMap(我知道这样的程序员太多了),请慎重。因为让你变得平凡的并不是项目进度紧或者工资低,而是对自己的要求不够高。
相关文章推荐
- Java HashMap 分析之四:查找和内存使用
- Java HashMap 分析之四:查找和内存使用
- Java HashMap 分析之四:查找和内存使用
- Java HashMap 分析之四:查找和内存使用
- java hashMap 简单使用以及深度分析
- Java程序内存分析:使用mat工具分析内存占用
- Java集合:HashMap使用详解及源码分析
- 使用jmap,jhat分析java应用内存
- java程序内存分析:使用mat工具分析内存占用
- 使用MAT分析Java内存
- java内存溢出分析工具:jmap使用实战
- Java程序内存分析:使用mat工具分析内存占用
- [转]使用Java Mission Control进行内存分配分析
- java内存分析(jmap和jhat使用)
- Java程序内存分析:使用MAT工具分析内存占用
- 关于Java的数据结构HashMap,ArrayList的使用总结及使用场景和原理分析
- Java程序内存分析:使用mat工具分析内存占用
- 用MAT分析JAVA程序运行时的内存使用情况
- Java中使用jvisualvm进行可视化内存分析
- Java程序内存分析:使用mat工具分析内存占用