繁体   English   中英

使用Hashmap保存大值时发生的outofmemory错误

[英]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将保存mToIdmType 使用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倍。
  • 我建议你使用TLongObjectHashMap,这将使存储密钥更有效。

这将使用每个条目大约64个字节。 如果你需要一个更紧凑的形式,你可以做到这一点,但复杂性越来越高。 每个条目不会超过20个字节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM