JNA调用本地动态库报错:EXCEPTION_ACCESS_VIOLATION (0xc0000005)JNA踩坑记录,JNA调用Harfbuzz

作者在项目中使用JNA调用Harfbuzz时遇到EXCEPTION_ACCESS_VIOLATION错误,问题源于JNA的Cleaner机制可能导致内存释放异常。解决方案是将JNA版本降低到3.2.7,以避免Cleaner影响内存管理。
摘要由CSDN通过智能技术生成

今天在做项目的时候,需要使用JNA去调用Harfbuzz去做文本整形,所以引用了jna.

jna介绍
JNA(Java Native Access )提供一组Java工具类用于在运行期间动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。使用结构体来做跨语言的数据交互,用java的类来做c或者c++库的接口封装;

我的报错代码如下:

A fatal error has been detected by the Java Runtime Environment:
 
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffd8c6b5bb6, pid=13076, tid=0x0000000000002a78
 
 JRE version: Java(TM) SE Runtime Environment (8.0_331-b09) (build 1.8.0_331-b09)
 Java VM: Java HotSpot(TM) 64-Bit Server VM (25.331-b09 mixed mode windows-amd64 compressed oops)
 Problematic frame:
 C  [ntdll.dll+0x25bb6]

该释放的我也释放了,这是内存释放的代码

// 释放内存
  public void close() {
    long peer =    Pointer.nativeValue(ptr);
    Native.free(peer);
    Pointer.nativeValue(ptr,0L);
  }

看java的报错日志

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  com.sun.jna.Native.free(J)V+0
j  com.sun.jna.Memory.free(J)V+7
j  com.sun.jna.Memory$MemoryDisposer.run()V+4
j  com.sun.jna.internal.Cleaner$CleanerRef.clean()V+15
j  com.sun.jna.internal.Cleaner$1.run()V+22
v  ~StubRoutines::call_stub

这里有人说是调用了两次的内存释放,其实不然,只是Memory.free去调用了Native.free;

这个问题困扰了我一周多,确实是内存访问出了问题,参考了网上很多的例子,最终都没有找到原因,突然发现JNA的Cleaner机制,会去释放内存,所以我的解决方式是将jna的版本降低到了3.2.7,因为JNA3.2.7没有Clear机制,甚至都没有Memory.free,我出现问题的版本是5.14.0;我估计是JNA的Cleaner机制的原因,JNA开了守护线程去Cleaner地址,这个需要研究一下JNA的clear机制才可以弄的清楚。

总结:最后的解决方式是换JNA的版本从5.14.0降低到3.2.7,更深层次的内容需要深究才可以弄明白,持续学习中。

2024.04.15更新博客:

基于github上的JNA项目的解释

https://github.com/java-native-access/jna/issues/1525

上面的内存释放是有问题的,所以才导致了这个问题,也就是说new Memory这种方式申请的内存也会被jvm进行管理。

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值