内存问题 - InputStream/OutputStream

4

没什么特别的,只是有点烦人。在这个ObjectInputStream$HandleTable$HandleList[]上使用了1.4GB的内存。

请查看图片以进行可视化

我使用ObjectInputStream和ObjectOutputStream将我的文件解析成一个二进制(.obj)文件。所以当然会出现这种情况。我更多地想知道是否存在某种“黑科技”来减少这种情况。也许。

已经尝试过input.close()和output.close(),但由于我的写入和读取被try/catch {}包围,这两个方法调用是多余的。

minlat = input.readFloat();
minlon = input.readFloat();
maxlat = input.readFloat();
maxlon = input.readFloat();
kdtreeCoastline = (KDTree) input.readObject();
kdtreeBicycle = (KDTree) input.readObject();

----

output.writeFloat(minlat);
output.writeFloat(minlon);
output.writeFloat(maxlat);
output.writeFloat(maxlon);
output.writeObject(kdtreeCoastline);
output.writeObject(kdtreeBicycle);

我并不期望它被缩减为0字节,但我想知道是否有人可能有想法。

提前感谢。


3
你应该寻找一种不同的(反)序列化机制,可以流式传输数据,而不需要将所有数据都保存在内存中。 - Moritz Petersen
2
你是使用 try-with-resources 还是只用 try-catch - Karol Dowbecki
你使用的是什么KDTree实现,是自定义的吗?这实际上决定了可能的解决方案。 - yegodm
@yegodm 这是自己的实现。 - rasm937k
@DodgyCodeException 使用了 VisualVM。 - rasm937k
显示剩余4条评论
3个回答

2

1) 尝试立即读取和写入输出,使对象有资格进行垃圾回收,并确保使用本地变量而不是字段,以便临时对象的生命周期不会延长到解析器的生命周期。

2) try/catch {} those two method calls are redundant. 除非您使用try-with语法(例如try(input = new ObjectInputStream(...))),否则try/catch不会关闭资源。

注:Original Answer翻译成"最初的回答"


实际上,我当然使用了try-with块。但是谢谢,这就是为什么它们是多余的原因。我的错。今天过得很长。 - rasm937k

1
"

HandleTable 的内存消耗表明您没有正确关闭 ObjectInputStreamObjectInputStream.close() 会在内部清除 HandleTable,这不是多余的,必须调用以清除句柄。

要么使用 try-with-resources,要么在 finally 中调用 close()。您不应该依赖 GC 在这里为您完成工作。

"

一个快速的查询:你说“你不应该依赖GC在这里为你工作。”但是还有其他选择吗?当你关闭文件时,close()方法的内部实现将使用你自己的话“内部清除HandleTable”。但是“内部清除HandleTable”实际上意味着什么?可能意味着删除所有对HandleTable的对象引用并允许其被垃圾回收-因此最终仍然依赖于GC来完成工作?也许OP看到HandleTable仍然被分配的原因是GC还没有回收它? - DodgyCodeException

1
默认序列化的问题在于它需要注册额外的标头(要序列化的类等),以及引用(据我所记,ObjectOutputStream 确保如果实例 A 和 B 依赖于实例 C,则使用 ObjectInputStream 时仍然为真;例如:你不能让 A 依赖于 C,而 B 依赖于 C)。这会占用一些空间。
  • 您可以尝试使用 DataInputStreamDataOutputStream 代替 ObjectOutputStream/ObjectInputStream,但是您的文件格式将更具体地适合您的需求,并且对数据格式的更改更加敏感。
  • 您还可以尝试实现 Serializable 的隐藏方法 writeObjectreadObject(请参见链接)来自定义对象的序列化形式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接