问题
1、用new Memory()
开辟空间,在GC的时候,整个服务崩溃。
报错A fatal error has been detected by the Java Runtime Environment
起因
原来的代码
结构体
public class Ty extends Structure {
public byte[] name = new byte[256];
public Pointer pValue = new Memory((1000) * Native.getNativeSize(Double.TYPE));
public TyVarValue() {
super();
}
public static class ByValue extends TyVarValue implements Structure.ByValue {
}
public static class ByReference extends TyVarValue implements Structure.ByReference {
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("name", "pValue");
}
}
修改后的代码
结构体
public class Ty extends Structure {
public byte[] name = new byte[256];
public Pointer pValue = new DoubleValue ().toArray(100000)[0].getPointer();
public TyVarValue() {
super();
}
public static class ByValue extends TyVarValue implements Structure.ByValue {
}
public static class ByReference extends TyVarValue implements Structure.ByReference {
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("name", "pValue");
}
}
double结构体
@Data
public class DoubleValue extends Structure {
public double value;// 0 var;1 signal
public DoubleValue() {
super();
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "value" });
}
public static class ByValue extends DoubleValue implements Structure.ByValue {
}
public static class ByReference extends DoubleValue implements Structure.ByReference {
}
}
错误原因分析
基础了解
- JNA 中的 Memory 对象分配的内存与 Java 中通过 new 关键字创建的内存有一些区别。
- 底层分配方式:
- Java 中使用 new 关键字创建的对象分配在 Java 堆上,由 Java 虚拟机自动进行垃圾回收。
- JNA 中的 Memory 对象分配的内存是通过调用本地库函数(如 C 语言的 malloc)在本地系统层面分配的内存,并不受 Java 垃圾回收的管理。
- 访问权限:
- Java 中通过 new 创建的对象受到 Java 安全管理器的保护,而且可以被 Java 运行时环境进行优化。
- JNA 中的 Memory 对象分配的内存具有直接的本机内存访问权限,可以通过指针直接与本机代码进行交互。
- 释放时机:
- Java 中通过 new 创建的对象由 Java 垃圾回收器自动管理释放。
- JNA 中的 Memory 对象需要手动调用 dispose 方法来释放内存,以避免内存泄漏。
- 底层分配方式:
- 在使用 JNA 中的 Memory 分配内存后,需要特别注意内存的释放时机。一般来说,应该在不再需要内存时手动调用 dispose 方法来释放内存。这通常发生在以下情况下,当 Memory 对象不再被需要,并且超出了对象的作用域范围时。在将 Memory 对象传递给本地库进行操作后,确保本地库操作完毕后即刻释放内存。
错误原因
- 在GC时,不能清除new Mermory的数据,导致GC崩溃。
- 我将其换成自定义结构体样式,将其空间创建交给JVM,释放也交给JVM,所以不会产生GC错误。