【发布时间】:2020-10-08 14:33:03
【问题描述】:
我们有一个 Java API,它是 C API 的包装器。 因此,我们最终得到了几个封装 C++ 类的 Java 类。
这些类实现 finalize 方法以释放已分配给它们的内存。
通常,这可以正常工作。但是,在高负载情况下,我们会出现内存不足异常。 内存转储表明几乎所有内存(在本例中约为 6Gb)都被终结器队列和等待终结的对象填充。
相比之下,C API 本身的内存使用量从未超过 150 Mb。
在低负载下,Java 实现可以无限期地运行。所以这似乎不是内存泄漏。似乎在高负载下,需要终结的新对象的生成速度比终结器的执行速度要快。
显然,“正确”的解决方法是减少正在创建的对象的数量。然而,这是一项重大的任务,需要一段时间。与此同时,是否有一种机制可以帮助缓解这个问题?例如,通过为 GC 提供更多资源。
【问题讨论】:
-
这就像在问,你的枪和膝盖之间的枕头应该有多厚。围绕用 C++ 实现的东西创建 Java 包装器还不错,但是在 Java 类和 C++ 类之间建立一对一的对应关系是两全其美的结合。
-
@Holger 是的,我明白这一点,但事实就是如此。我想我希望有人可能有一个凯夫拉枕头,我可以在将膝盖移到更安全的地方时使用它。 :)
-
使用direct
ByteBuffer可能会减少问题,因为实现会跟踪分配的本机内存量,并且能够减慢新分配的速度,直到处理完潜在的可回收缓冲区。当然,这完全取决于实现。
标签: java memory-management garbage-collection finalizer