java 堆内存不释放,JNA / ByteBuffer无法释放并导致C堆内存不足

首先,我对JNA和Java如何直接本机内存分配的理解充其量只是内在的,因此,我试图描述我对正在发生的事情的理解。除了回应以外的任何更正都会很棒。

我正在运行一个使用JNA混合Java和C本机代码的应用程序,并且遇到了一个可重现的问题,Java垃圾收集器无法释放对直接本机内存分配的引用,导致C堆内存不足。

我很肯定我的C应用程序不是分配问题的根源,因为我将A传递java.nio.ByteBuffer到我的C代码中,修改了缓冲区,然后在Java函数中访问了结果。在每个函数调用期间,我只有一个malloc和一个对应项free,但是在Java中反复运行代码后,malloc最终将失败。

这是显示问题的一些琐碎代码集- 实际上,我正在函数调用期间尝试在C堆上分配大约16-32MB 。

我的Java代码执行以下操作:

public class MyClass{

public void myfunction(){

ByteBuffer foo = ByteBuffer.allocateDirect(1000000);

MyDirectAccessLib.someOp(foo, 1000000);

System.out.println(foo.get(0));

}

}

public MyDirectAccessLib{

static {

Native.register("libsomelibrary");

}

public static native void someOp(ByteBuffer buf, int size);

}

然后我的C代码可能类似于:

#include

#include

void someOp(unsigned char* buf, int size){

unsigned char *foo;

foo = malloc(1000000);

if(!foo){

fprintf(stderr, "Failed to malloc 1000000 bytes of memory\n");

return;

}

free(foo);

buf[0] = 100;

}

麻烦的是,在反复调用此函数之后,Java堆有些稳定(增长缓慢),但是C函数最终无法分配更多的内存。在较高的层次上,我认为这是因为Java正在为C堆分配内存,但是由于Java

ByteBuffer对象相对较小,因此并未清除指向该内存的ByteBuffer。

到目前为止,我发现在我的函数中手动运行GC将提供所需的清除,但是这似乎既不是一个好主意,也是一个糟糕的解决方案。

如何更好地管理此问题,以便适当地释放ByteBuffer空间并控制C堆空间?

我对问题的理解是否不正确(是否运行不正确)?

编辑 :调整缓冲区大小以更能反映我的实际应用,我为图像分配大约3000x2000 …

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值