JavaCV native object deallocation

2019-09-15 04:22发布

问题:

What's wrong with the following JavaCV code? I try to populate CvSeq for further work, but the JVM almost reliably crashes with EXCEPTION_ACCESS_VIOLATION at various places, most often at [msvcr100.dll+0x3c19b] memcpy+0x20b or [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);
    }
}

In my configuration it fails most often after about 50000 iterations, but sometimes at other count or not at all. There is apparently some allocation/deallocation error. And it reproduces only when not running in debug mode.

If I explicitly call System.gc() after 20000 iterations, it fails inside cvSeqPush right after the GC (or 1-2 iterations later, probably because pointer from deallocated space happens to point to correct address). Or if I set both Xmx and Xms parameters, it fails sooner or later. Probably something in use is automagically deallocated.

回答1:

The problem is, that garbage collector recognizes memStorage as unused after it is last referenced in the code, not at the end of the block. This causes the native object deallocation just after the first GC that happened in the loop. That's why the problem reproduced only when not using debugger.

Solution is to add some reference to memStorage after the loop, to prevent GC from freeing it. The best is to call memStorage.release() to proactively free native memory without waiting to GC and preventing premature deallocation while it is still needed.

See my discussion with the JavaCV and JavaCPP author Samuel Audet with few more native allocation questions: https://groups.google.com/forum/?fromgroups=#!topic/javacv/ffQSkfXnT0o



标签: java javacv