由JNI Global引用持有的JPanel导致OOM异常

时间:2010-12-03 17:48:09

标签: java swing garbage-collection out-of-memory

我希望我的问题有更多的背景,但不幸的是,我是在绝望中发布这个问题。我无法用较小的应用程序重现这一点,因为我希望我可以在这里发布它。不幸的是,我所能做的只是尝试解释我的症状,并希望那里的人看到类似的东西。

我有一个纯粹的java应用程序,它在某些客户端计算机上获取OutOfMemoryExceptions。我提供400mb的Java堆空间,但不幸的是,我们仍然看到这个问题。在应用程序崩溃之前从我的应用程序中抓取堆转储,我可以看到有异常大量的JPanel对象。查看堆转储,有趣的是 ONLY 对我的面板的传入引用是“JNI Global Reference”。令我感到困惑的是,为什么首先会有一个 JNI 全局引用JPanel?我只有一帧。在什么情况下java需要创建一个JPanel的全局JNI引用?

虽然我有一个理论,但它不是基于我读过的任何东西,但我觉得终结器线程被阻止了。不幸的是,我没有一个线程转储来证明这一点。我的理论是,我的jpanel排队等待垃圾收集,然而,一旦它进入队列,队列本身就无法处理它。

有没有人愿意分享他们的理论或直觉?由于我无法在我的机器上重现这一点,因此在分析这一理论方面我有点被戴上手铐。但是,如果有人愿意给我另一条调查路线,我将非常感激。

编辑: 我对此有一个小的更新。我的应用程序也使用拖放,并分析堆转储更多,我注意到有尽可能多的java.awt.datatransfer.Transferable对象(它将我的JPanel作为transferable的一部分传递),因为有JPanels没有被清理干净了。有趣的是,对于Transferable对象的唯一引用是JNI Global。这让我想知道在清理JPanels时是否阻止了终结器,而是清理了拖放可传输对象。

编辑: 所以如果有人感兴趣,我相信我已经确定了问题。所以我在原帖中遗漏的是应用程序使用windows IE COM库(使用一些第三方库)嵌入HTML页面。无论如何,事实证明,当拖放发生时,第三方库或IE COM库本身会抓取JNI全局引用。不幸的是,我没有解决这个问题,但我要感谢那些在调查这个问题时向我发出建议的人。

1 个答案:

答案 0 :(得分:0)

假设Java Native Interface代码不是您自己的代码,您可能需要dispose()错误的图形上下文"if it was created directly from a component or another Graphics object."RotatableImage是一个在没有{{3}的情况下泄漏的示例}}