Java:大型 Guava Table 对象的序列化因内存不足错误而失败
Java: Serialization of large Guava Table object fails with out of memory error
我有一个大的 Guava
Table
对象,我正在尝试序列化:
import com.google.common.collect.Table;
Table<Integer, Integer, Double> pTable;
//
// Put lots of stuff into pTable
//
FileOutputStream fos = new FileOutputStream("pTable.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(pTable);
在最后一行我得到:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.io.ObjectOutputStream$HandleTable.growEntries(ObjectOutputStream.java:2346)
at java.io.ObjectOutputStream$HandleTable.assign(ObjectOutputStream.java:2275)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1427)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at java.util.HashMap.writeObject(HashMap.java:1129)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at java.util.HashMap.writeObject(HashMap.java:1129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
这个有fix/workaround吗?
它也适用于反序列化吗?
顺便说一下,pTable
表示一个大小约为 30000 X 30000 的密集矩阵,其中任何一对整数(每个都来自 30000 的集合)映射到一个浮点数 "distance" 之间他们。如果有比 Guava
的 Table
更紧凑的方式来表示这个矩阵,可以在合理的时间内创建并允许快速查找,我会很感兴趣。
你需要Increase heap size in Java.
例如
java -Xmx16g pTableProgram.jar
但是,如果您使用 [0..30000) 作为行键和列键,那么 double[][]
会使用更少的内存,并且如果您不需要 [=13= 的精度] 那么 float[][]
会用得更少。
例如
double[][] pTable = new double[30000][];
for (int i = 0; i < pTable.length; i++) {
pTable[i] = new double[30000];
}
//
// Put lots of stuff into pTable
//
FileOutputStream fos = new FileOutputStream("pTable.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(pTable);
我有一个大的 Guava
Table
对象,我正在尝试序列化:
import com.google.common.collect.Table;
Table<Integer, Integer, Double> pTable;
//
// Put lots of stuff into pTable
//
FileOutputStream fos = new FileOutputStream("pTable.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(pTable);
在最后一行我得到:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.io.ObjectOutputStream$HandleTable.growEntries(ObjectOutputStream.java:2346)
at java.io.ObjectOutputStream$HandleTable.assign(ObjectOutputStream.java:2275)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1427)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at java.util.HashMap.writeObject(HashMap.java:1129)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at java.util.HashMap.writeObject(HashMap.java:1129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
这个有fix/workaround吗? 它也适用于反序列化吗?
顺便说一下,pTable
表示一个大小约为 30000 X 30000 的密集矩阵,其中任何一对整数(每个都来自 30000 的集合)映射到一个浮点数 "distance" 之间他们。如果有比 Guava
的 Table
更紧凑的方式来表示这个矩阵,可以在合理的时间内创建并允许快速查找,我会很感兴趣。
你需要Increase heap size in Java.
例如
java -Xmx16g pTableProgram.jar
但是,如果您使用 [0..30000) 作为行键和列键,那么 double[][]
会使用更少的内存,并且如果您不需要 [=13= 的精度] 那么 float[][]
会用得更少。
例如
double[][] pTable = new double[30000][];
for (int i = 0; i < pTable.length; i++) {
pTable[i] = new double[30000];
}
//
// Put lots of stuff into pTable
//
FileOutputStream fos = new FileOutputStream("pTable.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(pTable);