《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一2.6.1 内存映射文件的性能

简介: 本节书摘来华章计算机《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一书中的第2章 ,第2.6.1节,[美] 凯S.霍斯特曼(Cay S. Horstmann) 著陈昊鹏 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.6.1 内存映射文件的性能

在本节的末尾,你可以发现一个计算传统的文件输入和内存映射文件的CRC32校验和的程序。在同一台机器上,我们对JDK的jre/lib目录中的37MB的rt.jar文件用不同的方式来计算校验和,记录下来的时间数据如表2-5
所示。
image

正如你所见,在这台特定的机器上,内存映射比使用带缓冲的顺序输入要稍微快一点,但是比使用RandomAccessFile快很多。
当然,精确的值因机器不同会产生很大的差异,但是很明显,与随机访问相比,性能提高总是很显著的。另一方面,对于中等尺寸文件的顺序读入则没有必要使用内存映射。
java.nio包使内存映射变得十分简单,下面就是我们需要做的。
首先,从文件中获得一个通道(channel),通道是用于磁盘文件的一种抽象,它使我们可以访问诸如内存映射、文件加锁机制以及文件间快速数据传递等操作系统特性。
image

然后,通过调用FileChannel类的map方法从这个通道中获得一个ByteBuffer。你可以指定想要映射的文件区域与映射模式,支持的模式有三种:

  • FileChannel.MapMode.READ_ONLY:所产生的缓冲区是只读的,任何对该缓冲区写入的尝试都会导致ReadOnlyBufferException异常。
  • FileChannel.MapMode.READ_WRITE:所产生的缓冲区是可写的,任何修改都会在某个时刻写回到文件中。注意,其他映射同一个文件的程序可能不能立即看到这些修改,多个程序同时进行文件映射的确切行为是依赖于操作系统的。
  • FileChannel.MapMode.PRIVATE:所产生的缓冲区是可写的,但是任何修改对这个缓冲区来说都是私有的,不会传播到文件中。
    一旦有了缓冲区,就可以使用ByteBuffer类和Buffer超类的方法读写数据了。

缓冲区支持顺序和随机数据访问,它有一个可以通过get和put操作来移动的位置。例如,可以像下面这样顺序遍历缓冲区中的所有字节:
image

用来读入在文件中存储为二进制值的基本类型值。正如我们提到的,Java对二进制数据使用高位在前的排序机制,但是,如果需要以低位在前的排序方式处理包含二进制数字的文件,那么只需调用
image

警告:这一对方法没有使用set/get命名惯例。
要向缓冲区写数字,可以使用下列的方法:
image
image

在恰当的时机,以及当通道关闭时,会将这些修改写回到文件中。
程序清单2-5用于计算文件的32位的循环冗余校验和(CRC32),这个数值就是经常用来判断一个文件是否已损坏的校验和,因为文件损坏极有可能导致校验和改变。java.util.zip包中包含一个CRC32类,可以使用下面的循环来计算一个字节序列的校验和:
image

注意:对CRC算法有一个很精细的解释,请查看http://www.relisoft.com/ Science/ CrcMath.html。
CRC计算的细节并不重要,我们只是将它作为一个有用的文件操作的实例来使用。(在实践中,每次会以更大的工夫而不是一个字节为单位来读取和更新数据,而它们的速度差异并不明显。)
应该像下面这样运行程序:

image
image
image
image

image
image
image
image
image
image

相关文章
|
4天前
|
存储 缓存 Java
面试官:什么是Java内存模型?
面试官:什么是Java内存模型?
38 0
面试官:什么是Java内存模型?
|
21天前
|
Java Linux
8 种 Java- 内存溢出六 -Out of swap space?
8 种 Java- 内存溢出六 -Out of swap space?
|
17天前
|
存储 Java
java的内存
java的内存需要划分成为5个部分: 1.栈(Stack)存放的都是方法中的局部变量。方法的运行一定要在栈当中运行。 2.堆(Heap)凡是new出来的东西,都是在堆当中 堆内存的东西都有一个地址值:16进制 堆内存的数据,都有默认值。规则: 整数 默认是0 浮点 默认0.0 字符 默认'\u0000' 布尔 默认false 引用类型 默认null 3.方法区(Method Area):存储class相关信息。包含方法的信息 4.本地方法栈(Native Method Stack):与操作系统相关 5.寄存器(pc Register):与cpu相关
23 6
|
21天前
|
算法 安全 Ubuntu
8 种 Java 内存溢出之八 -Kill process or sacrifice child
8 种 Java 内存溢出之八 -Kill process or sacrifice child
|
21天前
|
Java iOS开发 MacOS
8 种 Java- 内存溢出之四 -Metaspace
8 种 Java- 内存溢出之四 -Metaspace
|
1天前
|
监控 Java 编译器
优化Go语言程序中的内存使用与垃圾回收性能
【2月更文挑战第4天】本文旨在探讨如何优化Go语言程序中的内存使用和垃圾回收性能。我们将深入了解内存分配策略、垃圾回收机制,并提供一系列实用的优化技巧和建议,帮助开发者更有效地管理内存,减少垃圾回收的开销,从而提升Go程序的性能。
|
3天前
|
存储 Java
Java TreeMap:基于红黑树的排序映射解析
Java TreeMap:基于红黑树的排序映射解析
|
3天前
|
存储 缓存 安全
Java HashMap:哈希表原理、性能与优化
Java HashMap:哈希表原理、性能与优化
|
3天前
|
运维 监控 Java
Java在运维中的稳定性与性能优势技术分享
Java在运维中的稳定性与性能优势技术分享
|
3天前
|
存储 Java Unix
【JavaEE初阶】 认识文件与Java中操作文件
【JavaEE初阶】 认识文件与Java中操作文件