背景:
最近在做Cloud相关的项目的时候,使用libvirt-java调用libvirt代码,libvirt-java是使用JNA实现的,但是发现Libvirt-java中居然没有一个地方释放libvirt中分配的内存,和写libvirt-java的author讨论了一下,他认为返回Java指针指向C返回的结构,GC的时候会释放内存所以就不要处理,我觉得还是有问题,就做了如下测试:
测试代码:
C code:
void checkJNAMemLeak1(int **head, int *length)
{
long i = 0;
*head = (int *)malloc(sizeof(int) * 100000000);
for(i=0; i<100000000; i++)
{
(*head)[i] = 1;
}
*length = 100000000;
}
Java Code:
public void checkJNAMemLeak1(PointerByReference head, IntByReference length);
public static void testJNAMemLeak1()
{
PointerByReference head = new PointerByReference();
IntByReference length = new IntByReference();
while(true)
{
libben.checkJNAMemLeak1(head, length);
System.out.println(length.getValue());
sleep(1);
}
}
现象:
发现无论是虚拟内存还是驻留内存都狂涨,很快就超过了JVM设置的最大虚拟内存,这个时候用jconsole主动GC,发现没有任何小故宫
结论:
so中分配的内存,JNA需要主动封装释放内存的函数,否则会出现内存泄露