解决jna传java对象给动态库,java对象不释放的办法

       前段时间,公司做的项目需要调用动态so库文件,经研究后,决定采用jna技术。
开始定义一个结构体如下:


public class SecureStruct extends Structure {

public String sk;
public String srcDase64Data;
public int srcLen;
public String resBase64Data;
public int resLen;

protected List<String> getFieldOrder() {
List tmpLis = new ArrayList();
tmpLis.add("sk");
tmpLis.add("srcDase64Data");
tmpLis.add("srcLen");
tmpLis.add("resBase64Data");
tmpLis.add("resLen");
return tmpLis;
}

public void freeMemory() {
try {
resBase64Data = null;
sk = null;
srcDase64Data = null;
this.finalize();
} catch (Throwable e) {

e.printStackTrace();
}

}

}




jna 接口:


public interface JnaService extends Library {


/**
* 加密接口
* @param struct
* @return
*/
int symmEncryptData(SecureStruct struct);

/**
* 解密接口
* @param struct
* @return
*/
int symmDecryptData(SecureStruct struct);


}


调用代码:

SecureStruct struct = (SecureStruct) Structure.newInstance(SecureStruct.class);

JnaService().symmCleanData(struct);

注意问题来了,结构是new 出来的。每调用一次就要new一次。结构传入动态库so文件后,java垃圾回收机制是不会回收该对象的,随着调用的次数不断增加,内存结构体对象越来越多,最终会造成内存崩溃。


解决办法:


别传对象了,so动态库也不要申请内存,由jna申请好,以供so使用。核心代码如下:

int size = data.length + 1024 * 512;
Pointer out = new Memory(size);
long peer = Pointer.nativeValue(out);
IntByReference outLen = new IntByReference();
jnaService.jnaSymmEncryptData(data, data.length, sk, sk.length, out, outLen);
resDatas = out.getByteArray(0, outLen.getValue());
System.out.println("------------口返回的长度------------" + outLen.getValue());
Native.free(peer);
Pointer.nativeValue(out, 0);

这样每调用一次申请一次,用完就释放。

经测试,不会造成内存居高不下的问题。


猜你喜欢

转载自ywjun.iteye.com/blog/2393816