`

java的DirectBuffer源码分析(主要是DirectBuffer的资源分配和回收)

    博客分类:
  • java
阅读更多
可以看到淘宝的一个说明:http://www.tbdata.org/archives/801

Java 2 SE 6 doc :

Given a direct byte buffer, the Java virtual machine will make a best effort to perform native I/O operations directly upon it. That is, it will attempt to avoid copying the buffer’s content to (or from) an intermediate buffer before (or after) each invocation of one of the underlying operating system’s native I/O operations.

DirectBuffer通过免去中间交换的内存拷贝, 提升IO处理速度;

Java 2 SE 6 doc :

The contents of direct buffers may reside outside of the normal garbage-collected heap, and so their impact upon the memory footprint of an application might not be obvious.

DirectBuffer在-XX:MaxDirectMemorySize=xxM大小限制下[1], 使用Heap之外的内存, GC对此”无能为力”[2] ,也就意味着规避了在高负载下频繁的GC过程对应用线程的中断影响.
因此, 当系统应用场景满足:


大量原生类型数据使用
频繁IO操作
系统处理响应速度要求快且稳定
典型场景是网络数据传输, 可考虑合理应用DirectBuffer.


那么,DirectBuffer是怎么实现这些的呢:
DirectByteBuffer(int paramInt)
  {
    super(-1, 0, paramInt, paramInt, false);
    Bits.reserveMemory(paramInt);
    int i = Bits.pageSize();
    long l = 0L;
    try
    {
      l = unsafe.allocateMemory(paramInt + i); //这个是分配内存
    }
    catch (OutOfMemoryError localOutOfMemoryError)
    {
      Bits.unreserveMemory(paramInt);
      throw localOutOfMemoryError;
    }
    unsafe.setMemory(l, paramInt + i, 0);
    if (l % i != 0L)
      this.address = (l + i - (l & i - 1));
    else
      this.address = l;
    this.cleaner = Cleaner.create(this, new Deallocator(l, paramInt, null));//这个是负责回收资源。
    this.viewedBuffer = null;
  }



public native long allocateMemory(long paramLong);

allocateMemory 是一个本地方法,功能就是做一些参数检查和字节对齐,然后使用系统调用 malloc 申请一块内存。

从上面的分析也可以看出,创建一个 DirectByteBuffer 对象代价还是很大的,因为 malloc 系统调用代价就很大,需要 60 ~ 100 条 CPU 指令(一个 new Object() 只需要不足 10 条机器指令)。

注意,这个是操作系统直接分配的内存,java的垃圾回收是管不了的。


那是如何实现资源回收的呢。
 this.cleaner = Cleaner.create(this, new Deallocator(l, paramInt, null));

cleaner 的类型是Cleaner,Cleaner是PhantomReference(俗称的幽灵引用)的子类。当整个对象被回收的时候,幽灵引用会被java的虚拟机加到一个队列里去,ReferenceQueue。Reference有一个静态内部类ReferenceHandler。
 private static class ReferenceHandler extends Thread

然后还有个静态代码块:

 static
  {
    Object localObject1 = Thread.currentThread().getThreadGroup();
    for (Object localObject2 = localObject1; localObject2 != null; localObject2 = ((ThreadGroup)localObject1).getParent())
      localObject1 = localObject2;
    localObject2 = new ReferenceHandler((ThreadGroup)localObject1, "Reference Handler");
    ((Thread)localObject2).setPriority(10);
    ((Thread)localObject2).setDaemon(true);
    ((Thread)localObject2).start();
  }


也就是说虚拟机已启动,ReferenceHandler 这个线程就启动了,那ReferenceHandler 会做什么呢
public void run() {
	    for (;;) {

		Reference r;
		synchronized (lock) {
		    if (pending != null) {
			r = pending;
			Reference rn = r.next;
			pending = (rn == r) ? null : rn;
			r.next = r;
		    } else {
			try {
			    lock.wait();
			} catch (InterruptedException x) { }
			continue;
		    }
		}

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

		ReferenceQueue q = r.queue;
		if (q != ReferenceQueue.NULL) q.enqueue(r);
	    }
	}
    }


可以看到其中有:
if (r instanceof Cleaner) {
		    ((Cleaner)r).clean();
		    continue;
		}

就是会执行幽灵引用的clean方法。

在clean方法执行的其实是:
 this.thunk.run();

thunk是在构造方法传进去的。对于DirectByteBuffer来说,他的thunk是Deallocator:
this.cleaner = Cleaner.create(this, new Deallocator(l, paramInt, null))


Deallocator的run方法会做什么事情呢:
public void run() {
	    if (address == 0) {
		// Paranoia
		return;
	    }
	    unsafe.freeMemory(address);
	    address = 0;
	    Bits.unreserveMemory(capacity);
	}


  public native void freeMemory(long paramLong);


可以看到这个也是个native方法。这里就会把资源回收。


有些人问为什么不用finalize去做资源回收,搞个幽灵索引,搞怎么麻烦。主要是因为java的
finalize不是很安全。如果finalize再搞一个对象本身的强引用,那么这个对象就永远不会回收掉了。但是幽灵引用不一样,幽灵引用起作用在对象的finalize之后,也就是说这个对象这个时候已经回收了。这样会更安全。
7
2
分享到:
评论
5 楼 shuizhaosi888 2015-03-19  
解决我一个大问题  
4 楼 lazy_ 2013-04-17  
huangyunbin 写道


我想请问一下,这是否意味这directBuffer可以不受HEAP大小控制?例如JVM最大2G,堆分了1.5G,那么MaxDirectMemorySize最大可以是多少呢?

我的观点是:directBuffer的使用内存已经和jvm没有关系了,他的限制是操作系统或者硬件的限制了。


我们在32位机器的前提上讨论吧。一个进程4G空间,2G内核,2G用户。你的意思好像是,DIRECT BYTE BUFFER 用的是2G内核空间里面的空间。我的理解对吗?
3 楼 huangyunbin 2013-04-17  


我想请问一下,这是否意味这directBuffer可以不受HEAP大小控制?例如JVM最大2G,堆分了1.5G,那么MaxDirectMemorySize最大可以是多少呢?

我的观点是:directBuffer的使用内存已经和jvm没有关系了,他的限制是操作系统或者硬件的限制了。
2 楼 lazy_ 2013-04-17  
引用
DirectBuffer在-XX:MaxDirectMemorySize=xxM大小限制下[1], 使用Heap之外的内存, GC对此”无能为力”[2] ,也就意味着规避了在高负载下频繁的GC过程对应用线程的中断影响.


我想请问一下,这是否意味这directBuffer可以不受HEAP大小控制?例如JVM最大2G,堆分了1.5G,那么MaxDirectMemorySize最大可以是多少呢?
1 楼 mtsw2011 2013-04-17  
   

相关推荐

    nio Buffer internals

    直接缓冲区(Direct Buffer)是一个在堆外内存分配的缓冲区,它避免了在Java堆和JVM进行数据复制的开销,使数据传输更加高效。但是,直接缓冲区的创建和销毁成本较高,而且没有办法利用垃圾回收器来管理内存,因此...

    netty源码解析视频

    - 使用`DirectBuffer`而非`HeapBuffer`以减少垃圾回收压力。 - 合理设置TCP参数,如SO_KEEPALIVE、SO_REUSEADDR等。 - 调整线程池大小和队列长度等参数以适应不同场景下的性能需求。 4. **错误处理与异常捕获**...

    安川MP7系列工控系统源码解析:关键算法与硬件交互揭秘

    内容概要:本文深入剖析了安川MP7系列工业控制系统的关键源码,重点介绍了运动轨迹规划、通信协议处理以及故障处理机制等方面的技术细节。通过对实际代码片段的解读,揭示了该系统在硬件寄存器直接访问、特殊功能码处理等方面的独特之处。同时,文中还分享了一些基于实践经验得出的重要参数设置及其背后的故事,如特定摩擦补偿系数的选择原因等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对安川产品有一定了解并希望深入了解其内部工作机制的专业人士。 使用场景及目标:帮助读者掌握安川MP7系列控制器的工作原理,提高对类似系统的维护能力和故障排查效率。对于想要进一步研究或二次开发该系统的开发者来说,也能提供宝贵的参考资料。 其他说明:文章不仅限于理论讲解,还包括了许多来自一线的实际案例和经验教训,使读者能够更好地理解和应用所学知识。

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_.zip

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    风储直流微电网母线电压控制策略与双闭环MPPT技术研究

    内容概要:本文详细探讨了风储直流微电网中母线电压控制的关键技术。首先介绍了风储直流微电网的背景和发展现状,强调了母线电压控制的重要性。接着阐述了永磁风机储能并网技术,解释了永磁风机如何通过直接驱动发电机将风能转化为电能,并确保与电网的同步性和稳定性。然后深入讨论了双闭环控制MPPT技术,这是一种通过内外两个闭环控制系统来实现实时调整发电机运行参数的技术,确保风机始终处于最大功率点附近。最后,文章探讨了储能控制母线电压平衡的方法,即通过储能系统的充放电操作来维持母线电压的稳定。结论部分指出,通过这些技术的有机结合,可以实现对风储直流微电网的有效管理和优化控制。 适合人群:从事新能源技术研发的专业人士、电气工程研究人员、风电系统工程师。 使用场景及目标:适用于希望深入了解风储直流微电网母线电压控制策略的研究人员和技术人员,旨在帮助他们掌握最新的控制技术和方法,以提高系统的稳定性和效率。 其他说明:文章还对未来风储直流微电网的发展进行了展望,指出了智能化和自动化的趋势,以及储能技术的进步对系统性能的影响。

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    【操作系统开发】HarmonyOS目录结构详解:构建高效开发环境与跨设备协同应用

    内容概要:文章详细介绍了HarmonyOS的目录结构及其重要性,从整体框架到核心目录的具体功能进行了全面剖析。HarmonyOS凭借其分布式架构和跨设备协同能力迅速崛起,成为全球操作系统领域的重要力量。文章首先概述了HarmonyOS的背景和发展现状,强调了目录结构对开发的重要性。接着,具体介绍了根目录文件、AppScope、entry和oh_modules等核心目录的功能和作用。例如,AppScope作为全局资源配置中心,存放应用级的配置文件和公共资源;entry目录是应用的核心入口,负责源代码和界面开发。此外,文章还对比了HarmonyOS与Android、iOS目录结构的异同,突出了HarmonyOS的独特优势。最后,通过旅游应用和电商应用的实际案例,展示了HarmonyOS目录结构在资源管理和代码组织方面的应用效果。; 适合人群:具备一定编程基础,尤其是对移动操作系统开发感兴趣的开发者,包括初学者和有一定经验的研发人员。; 使用场景及目标:①帮助开发者快速理解HarmonyOS的目录结构,提高开发效率;②为跨设备应用开发提供理论和技术支持;③通过实际案例学习资源管理和代码组织的最佳实践。; 其他说明:HarmonyOS的目录结构设计简洁明了,模块职责划分明确,有助于开发者更好地管理和组织代码和资源。随着万物互联时代的到来,HarmonyOS有望在开发便利性和生态建设方面取得更大进展,吸引更多开发者加入其生态系统。

    飞轮储能充放电控制Simulink仿真模型:基于永磁同步电机的矢量控制与dq轴解耦

    内容概要:本文详细介绍了飞轮储能充放电控制的Simulink仿真模型,重点在于采用永磁同步电机的矢量控制和dq轴解耦控制策略。充电时,外环控制转速,内环控制dq轴电流;放电时,外环控制直流母线电压,内环同样控制dq轴电流。文中还讨论了硬件与软件环境的选择,以及仿真模型的调试与运行情况,最终得出该模型具有良好的跟随性能和波形完美度。 适用人群:从事电力电子系统、储能技术和Simulink仿真的研究人员和技术人员。 使用场景及目标:适用于需要对飞轮储能系统进行深入研究和仿真的场合,旨在提高充放电效率和稳定性,满足不同应用场景的需求。 其他说明:该仿真模型已调试完成,可以直接用于进一步的研究和实际应用,为未来的飞轮储能技术研发提供了有价值的参考。

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    1_15套python PDF格式.zip

    1_15套python PDF格式.zip

    三相三电平整流器仿真:基于电压电流双闭环控制与SPWM调制的性能分析

    内容概要:本文详细介绍了三相三电平整流器的仿真过程及其性能分析。文中首先概述了三相三电平整流器的基本概念及其在电力系统中的重要作用,接着重点探讨了电压电流双闭环控制方式的工作原理和优势,以及SPWM调制技术的具体应用。通过仿真文件展示了整流器在不同条件下的响应情况,验证了这两种技术的有效性和优越性。最后,作者表达了对未来实际应用的期望。 适合人群:从事电力电子研究的技术人员、高校相关专业师生、对电力控制系统感兴趣的工程爱好者。 使用场景及目标:适用于希望深入了解三相三电平整流器工作原理和技术细节的研究人员;目标是在理论基础上掌握电压电流双闭环控制和SPWM调制的实际应用方法。 其他说明:本文提供的仅为仿真文件,未涉及实物实验数据。

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    Arduino UART实验例程【正点原子EPS32S3】

    Arduino UART实验例程,开发板:正点原子EPS32S3,本人主页有详细实验说明可供参考。

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

Global site tag (gtag.js) - Google Analytics