记一次JNA的踩坑经历 -- JVM崩溃

问题

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 对象传递给本地库进行操作后,确保本地库操作完毕后即刻释放内存。

错误原因

  1. 在GC时,不能清除new Mermory的数据,导致GC崩溃。
  2. 我将其换成自定义结构体样式,将其空间创建交给JVM,释放也交给JVM,所以不会产生GC错误。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值