JNA内存源码解析Cleaner.CleanerRef,释放Native内存

源码:jna5.15.0

CleanerRef继承了虚引用PhantomReference,当Memory对象被GC的时候,把它的虚引用对象(PhantomReference)存入referenceQueue队列中,CleanerThread会一直轮询检查队列中是否有虚引用对象,如果有则触发clean方法。

private static class CleanerRef extends PhantomReference<Object> implements Cleanable {
	private final Cleaner cleaner;
	private final Runnable cleanupTask;
	private CleanerRef previous;
	private CleanerRef next;

	public CleanerRef(Cleaner cleaner, Object referent, ReferenceQueue<? super Object> q, Runnable cleanupTask) {
		super(referent, q);
		this.cleaner = cleaner;
		this.cleanupTask = cleanupTask;
	}

	@Override
	public void clean() {
        // 清理Native内存
		if(cleaner.remove(this)) {
			cleanupTask.run();
		}
	}

	CleanerRef getPrevious() {
		return previous;
	}

	void setPrevious(CleanerRef previous) {
		this.previous = previous;
	}

	CleanerRef getNext() {
		return next;
	}

	void setNext(CleanerRef next) {
		this.next = next;
	}
}

private class CleanerThread extends Thread {

	private static final long CLEANER_LINGER_TIME = 30000;

	public CleanerThread() {
		super("JNA Cleaner");
		setDaemon(true);
	}

	@Override
	public void run() {
		while (true) {
			try {
				Reference<? extends Object> ref = referenceQueue.remove(CLEANER_LINGER_TIME);
				if (ref instanceof CleanerRef) {
                    // 队列中有数据,代表对象被GC,触发定义的clean方法
					((CleanerRef) ref).clean();
				} else if (ref == null) {
					synchronized (referenceQueue) {
						Logger logger = Logger.getLogger(Cleaner.class.getName());
						if (firstCleanable == null) {
							cleanerThread = null;
							logger.log(Level.FINE, "Shutting down CleanerThread");
							break;
						} else if (logger.isLoggable(Level.FINER)) {
							StringBuilder registeredCleaners = new StringBuilder();
							for(CleanerRef cleanerRef = firstCleanable; cleanerRef != null; cleanerRef = cleanerRef.next) {
								if(registeredCleaners.length() != 0) {
									registeredCleaners.append(", ");
								}
								registeredCleaners.append(cleanerRef.cleanupTask.toString());
							}
							logger.log(Level.FINER, "Registered Cleaners: {0}", registeredCleaners.toString());
						}
					}
				}
			} catch (InterruptedException ex) {
				// Can be raised on shutdown. If anyone else messes with
				// our reference queue, well, there is no way to separate
				// the two cases.
				// https://groups.google.com/g/jna-users/c/j0fw96PlOpM/m/vbwNIb2pBQAJ
				break;
			} catch (Exception ex) {
				Logger.getLogger(Cleaner.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值