概述为什么Java内存映射缓冲区会导致大量意外的磁盘IO?
我写了一些利用映射文件缓冲区的Posix程序。 一个简单的scheme是将1GB文件映射到内存中,并用内容填充整个文件。
在程序执行期间,直到msync或munmap调用发生之前,几乎没有磁盘IO。
在完全相同的系统上,我在Oracle JDK 7上编写了运行Java的等效程序,并在整个程序执行过程中注意到大量的磁盘IO活动。
在JVM中如何实现内存映射文件缓冲区的不同? 无论如何要推迟大规模的IO活动吗?
底层物理内存用完时如何处理访问mmap-ed内存的总线错误?
设备内存空间中的cuda程序内核代码
windows内存pipe理器用于确定何时开始将页面交换到磁盘的阈值是多less?
32位和64位进程之间的memcpy性能差异
奇怪的行为:指针数与私有字节数
*** 作系统是linux 3.2 x64。
码:
import java.io.RandomAccessfile; import java.nio.MappedByteBuffer; import java.nio.channels.fileChannel; public class Main { public static voID main(String[] args) throws Exception { long size = 1024 * 1048576; RandomAccessfile raf= new RandomAccessfile(\”mmap1g\”,\”rw\”); fileChannel fc = raf.getChannel(); MappedByteBuffer buf = fc.map(fileChannel.MapMode.READ_WRITE,size); for(long i = 0; i < size; ++i) buf.put((byte)1); } }
访问linux用户空间中的硬件寄存器
将限制设置为linux中可用的总物理内存
在两个进程(C,windows)之间共享内存
执行缓冲区中的文件
为什么.bss部分映射到比目标文件中报告的bss小的进程?
内存映射完全在OS中实现。 除了通过force()方法和选择文件时的\”rws\”选项外,JVM在刷新磁盘时没有发言权。
linux将根据sysctl中设置的内核参数刷新到磁盘。
$ sysctl -a | grep dirty vm.dirty_background_bytes = 0 vm.dirty_background_ratio = 10 vm.dirty_bytes = 0 vm.dirty_expire_centisecs = 3000 vm.dirty_ratio = 20 vm.dirty_writeback_centisecs = 500
这些是我的笔记本电脑的默认设置。 比率10表示当主存储器的10%脏时,它将在后台开始将数据写入磁盘。 写回20%意味着写程序停止,直到脏百分比降到20%以下。 在任何情况下,数据将在3000厘秒或30秒后写入磁盘。
一个有趣的比较,它在内存映射tmpfs文件系统上的文件。 我把/tmp挂载为tmpfs,但大多数系统都有/ dev / shm。
顺便说一句你可能会觉得这个课有趣。 MemoryStore允许您映射任何大小的内存,即>> 2 GB,并在其上执行线程安全 *** 作。 例如你可以跨进程共享内存。 它支持堆锁,易失性读/写,有序写和CAS。
我有一个测试,其中两个进程锁定,切换,解锁记录,平均在我的笔记本电脑上的延迟是50纳秒。
BTW2:linux有稀疏的文件,这意味着你可以映射区域不仅大于你的主内存,但大于你的可用磁盘空间。 例如,如果映射8 TB,只使用4 GB的随机数据块,则会使用最多4 GB的内存和4 GB的磁盘。 如果使用du {file} ,则可以看到实际使用的空间。 注意:磁盘空间的惰性分配会导致高度碎片化的文件,这可能是HDD的性能问题。
总结
以上是内存溢出为你收集整理的为什么Java内存映射缓冲区会导致大量意外的磁盘IO?全部内容,希望文章能够帮你解决为什么Java内存映射缓冲区会导致大量意外的磁盘IO?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
请登录后查看评论内容