1

所以,下面的 java 代码在 finalize 期间会出现段错误。

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 个结构。

4

2 回答 2

0

所以我找到了我自己问题的答案,解决方案目前是半hacky。

问题是 JNA 调用__gmpz_clear与垃圾收集器在不同的线程上,有时垃圾收集器在__gmpz_clear完成执行之前会破坏指针数据和其他东西。通过添加自旋锁while(_mp_size > 0) ;完全解决了这个问题。

于 2012-07-17T20:11:18.183 回答
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();
            }
        };
    }
}

这确保了内存在被释放之前总是被“清除”。

于 2012-07-17T20:24:04.863 回答