我有一个包含 20000 个条目的 HashMap 。 HashMap 的形式为,
Map<Integer,Map<String,Object>> mapOne
我有方法将 map 写入文件。
public void createFiles(String fileName, Map map) throws IOException {
FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(map);
oos.close();
}
此方法通过尝试将 mapOne 写入文件时出现 java 堆空间错误。有没有其他更好的方法将 map 存储到文件中供以后使用?
JDK版本:1.7.0_17 mapOne 中的 map 包含独特的元素,以及 map 中对象的频率。
得到的错误信息:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.io.ObjectOutputStream$HandleTable.growEntries(Unknown Source)
at java.io.ObjectOutputStream$HandleTable.assign(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.util.HashMap.writeObject(Unknown Source)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.util.HashMap.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at TestIndex.AlignReads.createFiles(AlignReads.java:458)
at TestIndex.AlignReads.loadInputFiles(AlignReads.java:241)
at TestIndex.AlignReads.<init>(AlignReads.java:126)
at TestIndex.AlignReads.main(AlignReads.java:493)
最佳答案
这似乎不是一个非常大的HashMap。在调用您的程序时,您应该考虑增加堆(“内存”)大小。对于 Oracle 的 JDK 版本 1.7.0_17,这可以通过命令行开关 -Xms1g -Xmx1g
来完成。此示例将最大堆设置为 1 GB。当然,要使其完全有效,机器必须具有足够的(虚拟)内存资源。默认值可以低至 64 MB(小于 1 GB 的 10%),具体取决于具体条件。
关于你的第二个问题,你需要具体说明你认为“更好”的是什么。也就是说,在大多数情况下,像您一样使用标准对象序列化 API 是最佳选择。
第二个最常见的替代方法(有些人可能会说它实际上是第一个)是将信息存储在数据库中并根据需要从该信息构造对象。显然,如果出于某种原因您同时需要内存中的所有信息,那么您的进步并不大。
第三种选择(如果由于某种原因对象序列化 API 在这种特殊情况下行为不当(我对此表示怀疑)是有效的),不是序列化整个 map ,而是一次序列化每个元素。甚至每个数据项。这需要您在标准 API 之上定义特定于应用程序的序列化协议(protocol)。不是特别困难,但可能值得单独提问。
关于java - 将大型 HashMap 存储到 Java 文件中的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18306392/