0

以下 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 次迭代后失败,但有时在其他计数或根本没有。显然存在一些分配/解除分配错误。并且它仅在未在调试模式下运行时重现。

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

4

1 回答 1

1

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

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

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

于 2013-04-12T11:57:53.043 回答