[英]Occured outofmemory error when using Hashmap to save big values
我有一个简单的对象:
public class ActVO
{
private Long mFromId;
private Long mToId;
private int mType;
}
它也一直存在于Oracle DB中。 目前,存储的行在DB中大约有100万。 我想通过使用mFromId作为键将所有行读取到内存并缓存到HashMap。
我的问题是,当读取到400,000行时,它发生了内存错误(启动内存已准备好分配给1G)。 我使用cern.colt.map.OpenLongObjectHashMap和sun HasHmap它们都遇到了同样的问题。
每个人都可以告诉哪个第3个地图api或其他方式可以避免这个问题?
保存这么多不能适应可用内存的对象是不可能的。 有两种解决方案。 首先是使用缓存,该缓存将持久存储到无法放入内存的本地文件对象中。 像ehcache这样的东西。 第二种解决方案是使用对象切换到二维数组
long[][] cache = new long[1000*1000][];
long[] row = new long[2];
row
将保存mToId
和mType
。 使用mFromId
作为索引将行插入到cache
。
这是一个例子:
Random r = new Random();
class ActVO {
private long mFromId;
private long mToId;
private int mType;
}
int capacity = 1000*1000;
List<ActVO> resultSet = new ArrayList<ActVO>();
for (int i = 0; i < capacity; i++) {
ActVO element = new ActVO();
element.mFromId = i;
element.mToId = r.nextLong();
// let's say there are not more than 10 types
element.mType = r.nextInt(10);
resultSet.add(element);
if (i == 57) {
System.out.printf(" db result 57: mToId=%d, mType=%d\n", element.mToId, element.mType);
}
}
long[][] cache = new long[capacity][];
// iterating trough a database set
for (ActVO element : resultSet) {
long[] row = new long[2];
row[0] = element.mToId;
row[1] = element.mType;
cache[(int) element.mFromId] = row;
}
System.out.printf("57th row from cache: mToId=%d, mType=%d\n", cache[57][0], cache[57][1]);
我的建议是;
long
使用时,不要使用Long
。 它的内存可以大5倍。 这将使用每个条目大约64个字节。 如果你需要一个更紧凑的形式,你可以做到这一点,但复杂性越来越高。 每个条目不会超过20个字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.