0
点赞
收藏
分享

微信扫一扫

Java JNA (五)—— 释放Memory对象分配的内存

大雁f 2022-02-13 阅读 184


Java进程的内存包括​​Java NonHeap空间​​、​​Java Heap空间​​和​​Native Heap空间​​。

JNA中的Memory对象是从Native Heap中分配空间。但java的GC是针对Java Heap空间设计的,当Java Heap空间不足时会触发GC,但Native Heap空间不够却不会触发GC。

所以,当Java Heap占用空间不大时,并不会GC掉Memory对象,也就不会执行finalize()方法从而释放分配的Native Heap空间。

参考: http://ayufox.iteye.com/blog/723896

Memory中的finalize()方法:

/** Properly dispose of native memory when this object is GC'd. */
@Override
protected void finalize() {
dispose();
}

/** Free the native memory and set peer to zero */
protected synchronized void dispose() {
try {
free(peer);
} finally {
peer = 0;
allocatedMemory.remove(this);
}
}

protected static void free(long p) {
// free(0) is a no-op, so avoid the overhead of the call
if (p != 0) {
Native.free(p);
}
}

其中,Native.free()方法如下:

/**
* Call the real native free
* @param ptr native address to be freed; a value of zero has no effect,
* passing an already-freed pointer will cause pain.
*/
public static native void free(long ptr);

Pointer类中的方法:

/** Read the native peer value.  Use with caution. */
public static long nativeValue(Pointer p) {
return p == null ? 0 : p.peer;
}

/** Set the native peer value. Use with caution. */
public static void nativeValue(Pointer p, long value) {
p.peer = value;
}

由上面的源码可知,当Memory被GC掉时,会自动去释放分配的直接内存(前提是要执行GC)。为了避免过多的使用Memory分配直接内存而导致直接内存空间不足,可以手动释放掉Memory分配的内存,方法如下:

Pointer p = new Memory(1024 * 1024);
long peer = Pointer.nativeValue(p);
Native.free(peer);//手动释放内存
Pointer.nativeValue(p, 0);//避免Memory对象被GC时重复执行Nativ.free()方法

如果不调用最后一行代码

Pointer.nativeValue(p, 0);

则在GC时,会报错,并且程序异常退出。



举报

相关推荐

0 条评论