JavaCV本机对象释放

时间:2013-04-09 07:38:46

标签: java javacv

以下JavaCV代码有什么问题?我尝试填充CvSeq以进行进一步的工作,但JVM 几乎在各个地方可靠地与EXCEPTION_ACCESS_VIOLATION崩溃,最常见的是[msvcr100.dll+0x3c19b] memcpy+0x20b[opencv_core243.dll+0x61793] cvSeqPush+0x133

public static void main(String[] args) {
    CvMemStorage memStorage = CvMemStorage.create();
    CvSeq seq = cvCreateSeq(0, Loader.sizeof(CvSeq.class), 
          Loader.sizeof(CvPoint.class), memStorage);

    for (int j=0; j<1000000; j++) {
        CvPoint cvPoint = cvPoint(j, j+1);
        System.out.println(j);
        cvSeqPush(seq, cvPoint);
    }
}

在我的配置中,它经常在大约50000次迭代后失败,但有时在其他计数或根本没有。显然存在一些分配/解除分配错误。它只在不在调试模式下运行时才会重现。

如果我在20000次迭代后显式调用System.gc(),它会在GC之后立即在cvSeqPush内失败(或稍后1-2次迭代,可能是因为来自解除分配空间的指针恰好指向正确的地址)。或者,如果我同时设置了XmxXms个参数,它迟早会失败。可能正在使用的东西是自动解除分配的。

1 个答案:

答案 0 :(得分:1)

问题是,垃圾收集器在代码中最后一次引用后将memStorage识别为未使用,而不是在块的末尾。这会导致在循环中发生的第一个GC之后的本机对象释放。这就是为什么只在不使用调试器时才会重现问题。

解决方法是在循环后添加对memStorage的引用,以防止GC释放它。最好的方法是调用memStorage.release()主动释放本机内存而无需等待GC并防止在仍然需要时过早释放。

请参阅我与JavaCV和JavaCPP作者Samuel Audet讨论的更多原生分配问题:https://groups.google.com/forum/?fromgroups=#!topic/javacv/ffQSkfXnT0o