到目前为止,我一直使用pixDestroy来清理我的 JavaCPP/Leptonica 应用程序中的 PIX 对象。然而,我最近注意到一个奇怪的内存泄漏问题,我追踪到 Leptonica 函数在内部返回一个 pixClone 结果。我设法通过使用以下简单测试重现了该问题:
@Test
public void test() throws InterruptedException {
String pathImg = "...";
for (int i = 0; i < 100; i++) {
PIX img = pixRead(pathImg);
PIX clone = pixClone(img);
pixDestroy(clone);
pixDestroy(img);
}
Thread.sleep(10000);
}
当达到 Thread.sleep 时,Windows 任务管理器中的 RAM 内存使用量(不是堆大小)已增加到大约 1GB,并且在睡眠结束和测试完成之前不会释放。
查看pixClone的文档,我们看到它实际上创建了现有 PIX 的句柄:
笔记:
“克隆”只是现有像素的句柄(ptr)。它的实现是因为 (a) 图像可能很大,因此复制成本很高,并且 (b) 需要使用简单的策略对数据结构进行额外的处理,以避免双重释放和内存泄漏。Pix 是引用计数的。pixClone() 的副作用是引用计数增加 1。
要使用的协议是: (a) 每当您想要一个现有图像的新句柄时,调用 pixClone(),它只会增加一个引用计数。(b) 始终在所有句柄上调用 pixDestroy()。这会减少引用计数,使句柄为空,并且仅在对所有句柄调用 pixDestroy() 时才销毁 pix。
如果我理解正确,我确实在所有句柄上调用 pixDestroy,所以引用计数应该达到零,因此 PIX 应该被销毁。显然,情况并非如此。有人可以告诉我我做错了什么吗?提前致谢!