本文介绍了Java直接内存:在自定义类中使用sun.misc.Cleaner的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,NIO直接缓冲区分配的内存使用 sun.misc.Cleaner 实例释放,一些特殊的幻像引用比对象终结更有效。



这个更简洁的机制是仅在JVM中为直接缓冲子类硬编码的,还是可以在自定义组件中使用清理器(例如编写自定义直接字节缓冲区)? / p>

这里我不是在讨论检索现有nio直接缓冲区的清除字段。我不是在谈论手动释放内存。这是关于编写一个新类,它分配直接内存,并由垃圾收集器机制有效地自动清理。

解决方案

之后花更多时间阅读API文档()我想我有一个更详细的答案:



1)可以重用sun.misc.Cleaner来执行自己的自定义类的高效清理。您通过调用提供的工厂方法声明清理程序:

  sun.misc.Cleaner.create(Object ob,Runnable cleanup); 

有一段时间我无法让它正常工作,那是因为我足够愚蠢地定义我的清洁工作为匿名类的runnable清理代码,它保留了(强)引用我的指示对象,防止它幻影可达......



2)没有其他方法可以实现这种有效的清理(甚至没有幻像引用的帮助)



实际上,引用处理程序线程处理sun.misc.Cleaner的实例以一种特殊的方式:

  //清洁工的快速路径
if(r instanceof Cleaner){
((清洁)R)清洁机壳();
继续;
}

这意味着直接从引用处理程序线程调用清理代码,而在标准用法中,引用必须由引用处理程序线程排队,然后由另一个应用程序线程出列并处理。


In Java the memory allocated by NIO direct buffers is freed with sun.misc.Cleaner instances, some special phantom references that are more efficient than object finalization.

Is this cleaner mechanism hardcoded in the JVM only for the direct buffer subclasses, or is it possible to also use cleaners in custom components (writing a custom direct byte buffer for instance)?

Here I am not talking about retrieving the cleaner field of an existing nio direct buffer. I am not talking either about manually freeing the memory. This is about writing a new class that allocates direct memory and has it cleaned efficiently and automatically by the garbage collector mechanism.

解决方案

After spending more time reading the API doc ( http://docs.oracle.com/javase/7/docs/api/java/lang/ref/package-summary.html ) I think I have a more detailed answer:

1) it is possible to reuse sun.misc.Cleaner to perform the efficient cleanup of your own custom classes. You declare the cleaner by calling the provided factory method:

sun.misc.Cleaner.create(Object ob, Runnable cleanup);

For some time I could not get it to work properly, that's because I was moronic enough to define the runnable cleanup code of my cleaner as an anonymous class, that kept a (strong) reference to my referent object, preventing it from ever being "phantom reachable"...

2) There is no other way to implement such efficient cleanup (not even with the help of phantom references)

Indeed the reference handler thread handles instances of sun.misc.Cleaner in a special way:

// Fast path for cleaners
if (r instanceof Cleaner) {
    ((Cleaner)r).clean();
    continue;
}

That means that the cleanup code is called directly from the reference handler thread, while in standard usage, the references must be enqueued by the reference handler thread and then dequeued and processed by another application thread.

这篇关于Java直接内存:在自定义类中使用sun.misc.Cleaner的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-08 04:33