问题标签 [mappedbytebuffer]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
2504 浏览

java - 使用 MappedByteBuffer 读取大文件 ~14GB 文件

我正在尝试解决 I/O 密集型的生产者消费者问题。生产者常量将数据附加到文件中,消费者从这个不断增长的文件中读取。文件大小通常以 GB(约 10GB)为单位。

最初,我尝试使用 BufferedOutputStream 和 BufferedInputStream 读取数据并将数据写入文件。在上午 9:30 出现的数据突发期间,它占用了太多的系统 CPU 百分比,例如 30-40%(必须是 I/O 的系统调用)。

查看内存映射文件以使其更快。

1) 由于文件 readThisFile.dat size() 大于 INTEGER.MAX 长度 inChannel.map() 抛出异常。

2)消费者如何使用超大文件的内存映射文件不断读取数据。消费者每次可以加载 100MB 并继续寻找更多数据?

3)有没有更快的解决方案,比如在Java中尝试内存映射文件以外的东西?

0 投票
1 回答
242 浏览

java - 多线程 ByteBuffers 比顺序慢?

我有一个巨大的字节数组需要处理。理论上,应该可以将工作分成均匀的部分并将它们分配给不同的线程,以提高多核机器的性能。

我为每个线程分配了一个ByteBuffer,并分别处理了部分数据。即使我有 8 个逻辑处理器,最终性能也比单线程慢。也是非常不协调的。有时,相同的输入处理速度会慢一倍或更多。这是为什么?数据首先加载到内存中,因此不再执行任何IO操作。

我分配我的 ByteBuffers 使用MappedByteBuffer,因为它比ByteBuffer.wrap()

我使用以下方法进行并发处理Executors

并发任务performTask()使用它们自己的ByteBuffer实例从缓冲区中读取内存、进行计算等。它们不同步、不写入或相互影响。任何想法出了什么问题,或者这不是并行化的好例子吗?

同样的问题也ByteBuffer.wrap()存在MappedByteBuffer

0 投票
3 回答
1331 浏览

crash - Java 8 应用程序使用所有系统 RAM,然后因 SIGBUS 崩溃。这里发生了什么?

我有一个 Java 8 应用程序,它通过网络接收消息并使用 Java NIO MappedByteBuffer 写入多个内存映射文件。我有一个阅读器,它可以按顺序从这些文件中同时读取消息,并使用 MappedByteBuffer 再次删除读取的文件。一切都很顺利,直到我写入和读取了大约 246 GB 的数据并且我的应用程序因以下原因而崩溃

hs_err_pid44460.log是空的,核心转储core.44460的大小约为 246 GB,并且充满了我正在尝试编写的消息。

我运行的最大堆大小为 32 GB。根据 JConsole,我用完了Free Physical Memory然后崩溃。 JConsole 屏幕截图

为什么我的 RAM 用完了?我是否忘记关闭某些文件句柄/没有正确关闭我的 MMapped 文件?

0 投票
2 回答
490 浏览

java - 在内存有限的系统上写入大文件时如何避免 mapFailed() 错误

我刚刚在我的 opensrc 库代码中遇到了一个错误,该代码分配了一个大缓冲区来修改一个大的 flac 文件,该错误仅发生在使用 Java 1.8.0_74 25.74-b02 32bit 的具有 3Gb 内存的旧 PC 机器上

最初我只是分配一个缓冲区

但有一段时间我把它当作

我的(错误)理解是映射缓冲区比直接缓冲区使用更少的内存,因为整个映射缓冲区不必同时在内存中,只有正在使用的部分。但是这个答案说使用映射字节缓冲区是一个坏主意,所以我不清楚它是如何工作的

Java 大文件上传抛出 java.io.IOException: Map failed

完整的代码可以在这里看到

0 投票
0 回答
636 浏览

java - Android中的高性能文件IO

我正在创建一个与心电图监视器通信的应用程序。以每秒 250 个样本的速率读取数据。来自 ECG 监视器的每个包包含 80 个字节,每秒接收 40 次。

我试过使用 RandomAcccessFile,但包在同步 RandomAccessFile(outputFile, "rws")和异步 RandomAccessFile(outputFile, "rw")模式下都丢失了。

在最近的一个实验中,我尝试使用 MappedByteBuffer。这应该非常高效,但是当我创建缓冲区时,我必须指定map(FileChannel.MapMode.READ_WRITE, 0, 10485760)10MB 缓冲区的大小。但这会导致文件大小始终为 10MB。是否可以使用 MappedByteBuffer ,其中文件大小只是实际存储的数据量?

还是有另一种方法可以实现这一目标?这么频繁地写入文件是不是很幼稚?

附带说明一下,这在 iOS 上根本不是问题 - 这可以在完全没有缓冲的情况下实现。

0 投票
1 回答
443 浏览

cassandra - Cassandra SSTable 和内存映射文件

在这篇从 SSTable Perspective 阅读和写作的文章(是的,相当老的文章)中,作者说 indexdb 和 sstable 文件是使用内存映射文件预热的。

每个 SSTable 的行键存储在名为 index.db 的单独文件中,在启动期间,Cassandra “遍历这些文件”,以进行预热。Cassandra 使用内存映射文件,因此希望在启动期间读取文件时,首先从内存中访问这些文件。

我在 CommitLogSegment 中看到了 MappedByteBuffer 的使用,但不适用于 SSTable Loader/Reader。同样只是将 MappedByteBuffer 映射到文件通道不会将文件加载到内存中,我认为 load 需要显式调用。

所以我的问题是:当 Cassandra 启动时,它是如何预热的?我在这篇文章的声明中遗漏了什么吗?

0 投票
1 回答
1571 浏览

java - 调整、刷新和关闭 ByteBuffer

这实际上是关于如何使用内存映射文件的三个问题。我所做的工作,但我错过了一个权威的答案。

我得到我的ByteBuffer喜欢如下:

对于调整大小,以下似乎有效

没有打电话raf.getChannel(),但它真的正确吗?


根据Javadoc,调用force应该刷新它(我使用的是本地驱动器)。我只是想知道它是如何声明不的IOException如果它失败了会发生什么?


我必须关闭什么?, RandomAccessFile,FileChannel或两者兼而有之?我必须打电话flushMappedByteBuffer.force之前打电话吗?

0 投票
0 回答
324 浏览

android - 内存映射文件会干扰内存管理吗?

我编写了一个使用内存映射来访问文件的应用程序。读取速度显着提高,因此获得了成功。

正如预期的那样,分配给 的内存ByteBuffer不计入 VM 堆。在堆转储中,我的应用程序使用的内存似乎比实际使用的内存少得多。

我的问题是,这种分配对设备的内存管理有什么影响(如果有的话),因为它与其他应用程序有关? 它会让我的应用成为 Android 生态系统的“坏公民”吗?

0 投票
1 回答
262 浏览

java - MappedbyteBuffer.get() 将位置增加太多

我的文件的相关部分是这样的:

我在映射字节缓冲区中打开文件并将位置设置为开头。然后我这样做:

byteToUnsigned 方法只是做:

源最终是:“130.10.150.211”,而它应该是“130.10.150.201”。由于某种原因,get() 方法在大多数情况下将缓冲区的位置增加 1,但在第三次之后增加 5?正如您可能已经猜到的那样,我试图在之后解码目标 ip,它在“D3”之后开始读取,导致“0.102.19.8”


即使在 byteToUnsigned 调用之前,源 Ip 也是“-126.10.-106.-45”。


通过这一行一步步调试后:

观察 buffer.position() 和 buffer.get(),我可以看到以下内容:

  • 第一个get():buffer.position()=70,buffer.get()=-126
  • 第二个get():buffer.position()=71,buffer.get()=10
  • 第三个get():buffer.position()=72,buffer.get()=-106
  • 第四个 get(): buffer.position()= 73 , buffer.get()=-45

所以位置是正确递增的,但是第 72 和第 77 之间的字节不知何故对缓冲区不可见?


Api 明确指出:

我错过了什么?

0 投票
0 回答
153 浏览

java - java NIO MappedByteBuffer 没有同步内容的变化

我在一个场景中,一个进程A的多个线程将同时写入多个文件,然后进程B的多个线程将从这些文件中读取并在进程A完成后重新读取内容。内容可能很大,据说MappedByteBuffer可以加快速度。但是,我发现我写的更改并没有进入真实文件,因为当我xxd在写入过程终止后使用命令检查文件的内容时,它显示全为零(我确定实际内容字节不全为零因为我打印出来)

为了解决并发问题,我维护了一个AtomicInteger以确保只有在所有线程完成它们的工作之后,我才会force()将更改写入磁盘。这里是核心代码。

输出是这样的

queue_3:pos = 43112,limit = 10485760
queue_4:pos = 42407,limit = 10485760
queue_5:pos = 43254,limit limit = 10485760
topic_3:pos = 395296,limit = 395296,limit = 10485760
topic_ topic_ topic_ topic_ topic
= 4011236,401236,401236,401236,401236,4 , 限制 = 10485760
TOPIC_0 : 位置 = 392744, 限制 = 10485760

看起来很正常,但它只是不起作用......如何将这些更改同步到磁盘中?或者,即使它不必是