2016-07-27 32 views
2

我知道,对于I/O,直接字节缓冲区在本机堆上分配内存,而ByteBuffer在Java堆上分配内存,因此我们需要从中复制数据java堆到本地堆的I/O操作。为什么无法将数据直接读入地址空间而不是DirectByteBuffer

所以我的问题是,

是JVM的地址空间的直接ByteBuffer部分机堆?

如果不是的话为什么操作系统需要本地堆从套接字读取数据? 为什么不能直接从scoket读取数据到JVM的地址空间?或请求进程的地址空间。

我的目标:我是电子工程师。最近开始在java上开发一个需要最小延迟的项目。我有各种选项,多线程,jvm调优。这些问题是从我的分析中产生的,我会考虑这些选择。

+0

我不得不在这里猜测,但它可能是垃圾收集造成的,也就是说JVM必须能够移动内存以整理其堆释放收集的内存,并且不能让操作系统使用新的这样的操作后的地址。 – Thomas

回答

0

本地JVM的地址空间的直接bytebuffer部分的堆?

是的。

它只是在用于java对象并由GC管理的地址范围之外。

因为我们需要将数据从java堆复制到本地堆以进行I/O操作。

如果您使用的是二进制数据,您可以将其保存在DBB中,并使用访问器方法迭代其字节。这样,只有您访问的字节将被临时复制。非直接BB的优势在于您可以直接访问其支持byte[]阵列。但是如果你不需要,那么在某些情况下DBB可以更快。

可能的情景:

使用BB - >复制到本地
使用DBB - >没有复制需要
使用Java对象 - >连载至BB - >复制到本地
使用Java对象 - >连载到DBB - >没有额外的副本需要

在这些情况下,你会注意到使用DBB减少了复制。

这里有一个其中它不:

使用BB - >通过下面的阵列,以期待byte[]
使用DBB的方法 - >拷贝为byte [] - >传递到方法

在那些该方法需要重写为接受字节缓冲区。

最近开始在java上开发一个需要最小延迟的项目。我有各种选项,多线程,jvm调优。这些问题是从我的分析中产生的,我会考虑这些选择。

你真的不应该担心这样的低级细节。在优化之前进行测量。稍后您需要时,从BB切换到DBB是微不足道的。

+0

那么为什么我们要将数据从这个本地堆复制到java堆进行处理(例如解析)呢?那样我们不是在同一个地址空间中创建两份相同的数据吗?为什么我们不能直接处理本机堆中的数据?是否因为访问本地堆涉及JNI调用? – vvtx

+0

或者为什么我们不能将数据读入的本地堆的地址映射到java堆的某个地址?这样我们可以防止有多个副本。 – vvtx

+0

你提出了很多问题,但他们似乎是出于某个目标(我猜想性能)的动机......你应该编辑你的问题*来解释你正在尝试解决的实际问题*。我不想和你一起玩乒乓球比赛。 – the8472

相关问题