JavaCV本机对象重新分配 [英] JavaCV native object deallocation
问题描述
以下JavaCV代码有什么问题?我尝试填充CvSeq进行进一步的工作,但是JVM 几乎在不同地方(通常在[msvcr100.dll+0x3c19b] memcpy+0x20b
或[opencv_core243.dll+0x61793] cvSeqPush+0x133
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);
}
}
在我的配置中,它在大约50000次迭代后最常失败,但有时甚至不计其数.显然存在一些分配/取消分配错误.而且仅在未在调试模式下运行时才会复制.
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.
如果我在20000次迭代后显式调用System.gc()
,它会在GC之后(或稍后的1-2次迭代)在cvSeqPush
内部失败,这可能是因为释放空间的指针恰好指向正确的地址.或者,如果同时设置了Xmx
和Xms
参数,则迟早会失败.可能正在自动释放使用中的东西.
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.
推荐答案
问题是,垃圾回收器在最后一次在代码中引用memStorage
之后,而不是在代码块的末尾将memStorage
识别为未使用.这会导致在循环中发生第一个GC之后立即释放本机对象.这就是为什么仅在不使用调试器时才会重现该问题的原因.
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.
解决方案是在循环后为memStorage
添加一些引用,以防止GC释放它.最好的方法是调用memStorage.release()
来主动释放本机内存,而不必等待GC并防止在仍然需要时进行过早释放.
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.
请参阅我与JavaCV和JavaCPP作者Samuel Audet的讨论,其中还有其他一些本机分配问题: https://groups.google.com/forum/?fromgroups=#!topic/javacv/ffQSkfXnT0o
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
这篇关于JavaCV本机对象重新分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!