所以,在finalize期间,下面的java代码段错误。
public class Mpz_t extends com.sun.jna.Structure {
public int _mp_alloc;
public int _mp_size;
public NativeLongByReference _mp_d;
protected void initFieldOrder() {
setFieldOrder(new String[] { "_mp_alloc", "_mp_size", "_mp_d" });
}
public Mpz_t() {
super();
initFieldOrder();
allocateMemory();
ensureAllocated();
}
public static class ByReference extends Mpz_t implements
Structure.ByReference {
}
public static class ByValue extends Mpz_t implements
Structure.ByValue {
}
@Override public void finalize() {
Gmp.gmp().__gmpz_clear(this);
}
}
据我所知, .__gmpz_clear()
会破坏C端的结构。如果我撕掉那个部分,就没有段错误,但我的代码会泄漏内存。有人有这方面的想法吗?
我可能会补充一点,它不能可靠地进行段错误。在问题发生之前,它会正确地破坏这些结构中的20个。
答案 0 :(得分:0)
所以我找到了自己问题的答案,解决方案目前是半熟的。
问题是JNA对__gmpz_clear
的调用与垃圾收集器位于不同的线程上,有时垃圾收集器会在__gmpz_clear
完成执行之前销毁指针数据和其他内容。通过while(_mp_size > 0) ;
添加螺旋锁完全解决了这个问题。
答案 1 :(得分:0)
为了确保清理以正确的顺序运行,您可以考虑覆盖Structure.autoAllocate(int size)
以返回自定义Memory
对象,该对象会扩充其现有的终结器,以便在现有之前调用__gmpz_clear
终结器实际上释放了分配的内存。
public class Mpz_t extends Structure {
protected Memory autoAllocate(int size) {
return new Memory(size) {
protected void finalize() {
GMP.gmp().__gmpz_clear(this);
super.finalize();
}
};
}
}
这可以确保在释放内存时总是“清除”。