- 浏览: 2609353 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (880)
- 每日总结 (26)
- java (37)
- lucene 2.4源码学习 (11)
- 庖丁分词的源码分析 (5)
- cindy源码阅读 (10)
- jetty (3)
- java基础 (49)
- hadoop (37)
- python (7)
- 那些蛋疼的事 (15)
- 测试 (5)
- spring (3)
- redis (4)
- git (4)
- 我的开源项目 (2)
- linux (15)
- mysql (8)
- bootsharp (1)
- idea (1)
- Disruptor源码分析 (11)
- 高并发 (22)
- jdk (4)
- 领域驱动 (1)
- 坑 (6)
- 表达式框架 (7)
- 游戏 (3)
- Guava (1)
- 缓存 (1)
- 数据库 (1)
- 游戏项目 (3)
- java8 (1)
最新评论
-
hsluoyz:
PyCasbin是一个用Python语言打造的轻量级开源访问控 ...
权限管理的一个简单后台 -
liuyachao111:
谢谢 问题解决了
对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾 -
jnjeC:
多谢博主分享,在配置文件里的&也要改成& ...
对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾 -
大维啊:
同志,你这不行啊!
java 的 AccessController.doPrivileged使用 -
lisha2009:
解决了我的问题,多谢博主分享!
对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾
可以看到淘宝的一个说明: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是怎么实现这些的呢:
allocateMemory 是一个本地方法,功能就是做一些参数检查和字节对齐,然后使用系统调用 malloc 申请一块内存。
从上面的分析也可以看出,创建一个 DirectByteBuffer 对象代价还是很大的,因为 malloc 系统调用代价就很大,需要 60 ~ 100 条 CPU 指令(一个 new Object() 只需要不足 10 条机器指令)。
注意,这个是操作系统直接分配的内存,java的垃圾回收是管不了的。
那是如何实现资源回收的呢。
cleaner 的类型是Cleaner,Cleaner是PhantomReference(俗称的幽灵引用)的子类。当整个对象被回收的时候,幽灵引用会被java的虚拟机加到一个队列里去,ReferenceQueue。Reference有一个静态内部类ReferenceHandler。
然后还有个静态代码块:
也就是说虚拟机已启动,ReferenceHandler 这个线程就启动了,那ReferenceHandler 会做什么呢
可以看到其中有:
就是会执行幽灵引用的clean方法。
在clean方法执行的其实是:
thunk是在构造方法传进去的。对于DirectByteBuffer来说,他的thunk是Deallocator:
Deallocator的run方法会做什么事情呢:
可以看到这个也是个native方法。这里就会把资源回收。
有些人问为什么不用finalize去做资源回收,搞个幽灵索引,搞怎么麻烦。主要是因为java的
finalize不是很安全。如果finalize再搞一个对象本身的强引用,那么这个对象就永远不会回收掉了。但是幽灵引用不一样,幽灵引用起作用在对象的finalize之后,也就是说这个对象这个时候已经回收了。这样会更安全。
我想请问一下,这是否意味这directBuffer可以不受HEAP大小控制?例如JVM最大2G,堆分了1.5G,那么MaxDirectMemorySize最大可以是多少呢?
我的观点是:directBuffer的使用内存已经和jvm没有关系了,他的限制是操作系统或者硬件的限制了。
我们在32位机器的前提上讨论吧。一个进程4G空间,2G内核,2G用户。你的意思好像是,DIRECT BYTE BUFFER 用的是2G内核空间里面的空间。我的理解对吗?
我想请问一下,这是否意味这directBuffer可以不受HEAP大小控制?例如JVM最大2G,堆分了1.5G,那么MaxDirectMemorySize最大可以是多少呢?
我的观点是:directBuffer的使用内存已经和jvm没有关系了,他的限制是操作系统或者硬件的限制了。
我想请问一下,这是否意味这directBuffer可以不受HEAP大小控制?例如JVM最大2G,堆分了1.5G,那么MaxDirectMemorySize最大可以是多少呢?
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之后,也就是说这个对象这个时候已经回收了。这样会更安全。
评论
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
发表评论
-
超级简单的获取url内容的代码
2016-09-09 16:33 1564只是需要一行代码: String result = new S ... -
java的int和byte数组的相互转换
2015-01-15 16:31 2913byte数组转为int 有两种原理, 一种是先左移动24位,在 ... -
@RequestBody注解时 HttpClient 发送post的例子
2015-01-12 10:33 6758主要是这句: post.setRequestEntity(ne ... -
mvel表达式遇到的坑2 这个更坑
2015-01-09 17:53 6737之前写的一篇文章说的mvel遇到的坑 解决办法是*1.0,这次 ... -
利用javassist获取java的方法参数名
2014-03-22 20:53 6364import java.lang.reflect.Meth ... -
java利用linq4j实现linq
2014-01-13 20:58 10503public class Person implement ... -
访问类本身的私有变量,很不理解的地方
2013-09-30 17:50 1638网上看到这个文章,表示没理解.http://my.oschin ... -
设置log4j的配置文件(里面有不少坑)
2013-04-12 15:59 2009log4j的默认配置文件是log4j.properties,加 ... -
庖丁分词的源码分析
2013-04-08 17:50 3108在网上也看到了不少庖 ... -
eclipse代码行数统计插件
2013-04-08 16:14 6024觉得不错的一个插件,把附件里的压缩文件,解压,放在eclips ... -
关于eclipse 找不到pom文件中的jar包的问题
2013-04-08 15:59 2261我从网上下载呢一个maven的项目,install也成功了,却 ... -
java的volatile与多线程
2013-02-21 16:37 2195Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员 ... -
分享视频网站的内容时 缩略图的生成
2013-02-03 09:32 1918分享视频网站的内容时 ,一般都有缩略图的生成,之前没怎么关心, ... -
Runtime.getRuntime().exec 杀人放火利器啊
2013-01-05 16:49 2259public static void main(String[ ... -
split的正则表达式
2012-12-24 14:44 1514我们很经常做得一个事情,一句话,按空格来切分 String s ... -
解决eclipse控制台中文乱码的问题
2012-12-20 14:48 3126二、配置java应用程序的控制台输出。 1.Run ... -
eclipse 重新关联源代码
2012-12-17 09:16 1681eclipse 重新关联源代码 可以右键工程属性 -- pr ... -
maven私服的400和401错误
2012-12-03 17:33 2803400错误是因为没有打开访问,改为下图这样 401错误是没 ... -
SQL_NO_CACHE不起作用,郁闷
2012-12-03 14:53 1770mysql设置了查询缓存,但是第二次的时候就是0秒了,用SQL ... -
ie下onblur和focus自身引起的浏览器卡死,求解释
2012-12-01 17:12 3002代码 <!DOCTYPE HTML PUBLIC &q ...
相关推荐
Java 中 Buffer 源码的分析 Java 中 Buffer 源码的分析是 Java 中一个非常重要的知识点, Buffer 是 Java 中用于高效进行 IO 操作的缓冲区。Buffer 分为两类:Direct Buffer 和 Heap Buffer。下面将详细介绍这两类 ...
Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...
它负责维护一组`PoolChunkList`实例,并提供了一套完整的策略来分配和回收内存。 **5. 从对象池中获取 buffer** 为了从对象池中获取`ByteBuf`实例,用户可以通过`PooledByteBufAllocator`提供的方法来请求特定大小...
Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java...
标题“Java远程监控源码”涉及的是Java编程中关于远程监控和控制的实现。这个项目可能包含一个客户端(client)和服务器端(server)的架构,通过Socket通信进行数据交互,利用Java Robot类来捕获屏幕图像,以及...
总的来说,这份Java人脸识别源码是一个很好的学习和实践资源,它可以帮助开发者深入理解特征脸识别技术以及如何在Java环境中使用JavaCV来处理图像和视频。通过研究和调试代码,可以提升在计算机视觉领域的专业技能。
JAVA源码DataBuffer在Java中使用ADO.NET
源码分析可以帮助读者理解和运用这些机制,编写出高效、安全的并发程序。 文件I/O操作在任何编程语言中都是必不可少的。Java的File类和InputStream/OutputStream家族提供了丰富的功能,用于读写文件和处理流。通过...
在分析和使用这套源码时,开发者需要对Java编程、Web开发框架、数据库管理和电子商务业务流程有深入理解。由于缺少Struts的jar包,开发者需要自行解决这个问题,或者选择使用其他框架进行重构。同时,对源码的充分...
总结来说,Java中使用DataBuffer与ADO.NET交互主要依赖于JNA这样的库来实现跨平台的调用。这个过程涉及了对.NET接口的映射、数据缓冲区的管理以及Java和.NET数据类型的转换。尽管这提供了一种灵活性,但在实际应用中...
本文将深入探讨基于Java实现RTSP服务的相关知识点,并以“基于Java的RTSP服务源码”为例进行分析。 1. RTSP协议基础 RTSP协议由IETF定义,主要目的是为了解决多媒体数据的实时传输问题。它允许客户端通过发送指令来...
他们可以研究源码,理解Java和ADO.NET之间的交互机制,并扩展这个例子以适应不同的数据库需求。 总结来说,这个基于Java的实例开发源码展示了如何在非.NET环境中利用ADO.NET的强大功能。通过学习和理解这个例子,...
Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java...
java源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码源码...
一个pc下的java炸弹人实现及源码
Hadoop源码分析是深入理解Hadoop分布式计算平台原理的起点,通过源码分析,可以更好地掌握Hadoop的工作机制、关键组件的实现方式和内部通信流程。Hadoop项目包括了多个子项目,其中最核心的是HDFS和MapReduce,这两...
这个"129个Java项目源码下载"集合提供了一个极好的学习资源,涵盖了各种类型的Java应用项目,帮助开发者深入理解Java编程的实际运用。 在Java项目开发中,我们通常会遇到多种技术栈和框架,例如Spring Boot用于构建...
在Java 2D API中,`DataBuffer` 是图像数据的主要存储结构,通常与`Raster` 和 `BufferedImage` 类一起使用来处理图像。在ADO.NET中,虽然没有直接对应的`DataBuffer`概念,但在处理数据库数据时,我们会用到类似的...
基于Java的实例源码-DataBuffer在Java中使用ADO.NET.zip
权限管理通过角色和权限的分配,限制不同用户对资源的访问;日志记录有助于追踪操作历史,便于问题排查;异常处理则可以防止程序因意外情况崩溃,提高系统的健壮性。 总的来说,这个人力资源管理系统利用Java Web...