【问题标题】:understanding channel in java.nio packagejava.nio包中的理解通道
【发布时间】:2014-11-14 12:19:17
【问题描述】:

对于直接映射缓冲区,它们始终位于 jvm 堆之外。另一方面,通道似乎也存在于 IO 操作中。我只是想知道直接映射缓冲区的相应通道是否也保留在 jvm 堆之外?

另外,另一个问题来自于内存操作效率方面Channel存在的必要性。我明白了

通道表示与实体(例如硬件设备)的开放连接

然而,在通过直接映射缓冲区写入文件的情况下,内容是否被写入了两次?内容首先写入缓冲区,然后写入通道。与“直接”写入 IO 设备相比,这会是低效率吗?

【问题讨论】:

    标签: java io buffer nio


    【解决方案1】:

    我只是想知道直接映射缓冲区的相应通道是否也在 jvm 堆之外?

    这个问题没有意义。 Channel 不是一块内存,它是操作系统 FD 的接口。

    在通过直接映射缓冲区写入文件的情况下,内容是否被写入两次?内容首先写入缓冲区,然后写入通道。与“直接”写入 IO 设备相比,这会是低效率吗?

    没有。 MappedByteBuffer 独立于它来自的频道。例如关闭通道时不关闭。

    您是否正在寻找直接的 byte 缓冲区?它们确实存在,您通过通道写入它们,但通过它们的 I/O 发生一次,而不是两次。

    【讨论】:

    • 感谢您的回答。假设我正在写入文件。这是否意味着它首先对缓冲区进行非IO写入,然后通过通道IO写入真实文件?
    • 对于缓冲区本身,如果我从 JNI 获取它的起始地址,并且知道内存中的对象布局(知道实际内容的偏移量)。是否保证我实际上可以从该起始地址+偏移量中获取真实的文件内容?
    • @jer_yin 您似乎从未编写过任何 NIO 代码。 将数据放入缓冲区,然后调用channel.write(buffer).进行读取,调用channel.read(buffer),然后从缓冲区中获取数据。
    • 我问这个问题也不是为了写 NIO 代码。
    【解决方案2】:

    我想我知道答案了。

    直接映射缓冲区首先写入一个缓冲区,这是非IO操作。用于更新文件的实际写入的 IO 操作随后发生。两次写入的原因是因为我们有 DMA,我们不希望所有的 IO 操作都按次发生。一次所有 IO 操作效率更高。

    通过 JNI 获取的起始地址不是访问那块内存的正确地址。相反,数据的地址是隐藏在 java.nio.buffer 中的一个字段。获取该字段的一种方法是通过 sun.misc.Unsafe 公开该字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-11
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      • 1970-01-01
      • 2018-03-31
      • 1970-01-01
      相关资源
      最近更新 更多