Java内存映射原理与实现

Java内存映射原理与实现Java虚拟机规范中定义了Java内存模型(JavaMemoryModel,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。

大家好,又见面了,我是你们的朋友全栈君。

01. 虚拟内存与内存映射文件

1.1. 概念

  • 虚拟内存
    虚拟内存属于硬盘的一部分,是计算机RAM与硬盘的数据交换分区

    由于实际的物理内存远小于进程的地址空间,这就需要把内存中暂时不用到的数据放到硬盘上一个特殊的地方,当请求的数据不在内存中时,系统产生却页中断,内存管理器便将对应的内存页重新从硬盘调入物理内存。

  • 内存映射文件
    内存映射文件是由一个文件到一块内存的映射。

    应用程序可以通过内存指针对磁盘上的文件进行访问,就如同访问加载了文件的内存,因此内存文件映射非常适合于用来管理大文件。

1.2 区别

  • 磁盘文件
    虚拟内存使用的硬盘只能是页面文件
    内存映射使用的磁盘可以是任何磁盘文件。
  • 架构
  1. 虚拟内存是架构在物理内存之上。

    引入原因:实际的物理内存运行程序所需的空间。即使现在计算机中的物理内存越来越大,程序的尺寸也在增长,将所有运行着的程序全部加载到内存中不经济也非常不现实。

  2. 内存映射文件架构在程序的地址空间之上

    32位机地址空间只有4G,而某些大文件的尺寸可要要远超出这个值,因此,用地址空间中的某段应用文件中的一部分可解决处理大文件的问题,在32中,使用内存映射文件可以处理2的64次(64EB)大小的文件.原因内存映射文件,除了处理大文件,还可用作进程间通信。

02. 内存映射文件的原理

“映射”就是建立一种对应关系,主要是指硬盘上文件的位置与进程逻辑地址空间中一块相同区域之间一一对应。这种关系纯属是逻辑上的概念,物理上是不存在的,原因是进程的逻辑地址空间本身就是不存在的,在内存映射过程中,并没有实际的数据拷贝,文件没有被载入内存,只是逻辑上放入了内存,具体到代码,就是建立并初始化了相关的数据结构,这个过程有系统调用mmap()实现,所以映射的效率很高。
在这里插入图片描述
上面说到建立内存映射没有进行实际的数据拷贝,那么进程又怎么能最终通过内存操作访问到硬盘上的文件呢?

  1. 调用mmap(),相当于要给内存映射文件分配了虚拟内存,它会返回一个指针ptr,这个ptr所指向的是一个逻辑地址,要操作其中的数据,必须通过MMU(Memory Management Unit,即内存管理单元)将逻辑地址转换成物理地址,如图1中过程2所示。
  2. 建立内存映射并没有实际拷贝数据,这时MMU在地址映射表中是无法找到与ptr相对应的物理地址的,也就是MMU失败,将产生一个缺页中断,缺页中断的中断响应函数会在swap(也就是交换分区)中寻找相对应的页面,如果找不到(也就是该文件从来没有被读入内存的情况),则会通过mmap()建立的映射关系,从硬盘上将文件读取到物理内存中,如图1中过程3所示。
  3. 如果在拷贝数据时,发现物理内存不够用,则会通过虚拟内存机制(swap)将暂时不用的物理页面交换到硬盘上,如图1中过程4所示。

03. 内存映射文件的效率

了解过内存映射文件都知道,它比传统的IO读写数据快很多,那么,它为什么会这么快,从代码层面上来看,从硬盘上将文件读入内存,都是要经过数据拷贝,并且数据拷贝操作是由文件系统和硬件驱动实现的,理论上来说,拷贝数据的效率是一 样的。其实,原因是read()是系统调用,其中进行了数据拷贝,它首先将文件内容从硬盘拷贝到内核空间的一个缓冲区,如图2中过程1,然后再将这些数据拷贝到用户空间,如图2中过程2,在这个过程中,实际上完成 了两次数据拷贝 ;而mmap()也是系统调用,如前所述,mmap()中没有进行数据拷贝,真正的数据拷贝是在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间,只进行了 一次数据拷贝 。因此,内存映射的效率要比read/write效率高。
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/151749.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月21日 下午8:00
下一篇 2022年6月21日 下午8:00


相关推荐

  • 音乐推荐系统(协同过滤和SVD)

    音乐推荐系统(协同过滤和SVD)python 音乐推荐系统协同过滤和 SVD 矩阵分解 importpandas home 数据提取提取用户 歌曲 播放量 triplet dataset pd read csv filepath or buffer data home train triplets txt sep t header

    2025年9月6日
    9
  • python检查文件更新失败_恢复自动更新/更新失败解决方法个人汇总[通俗易懂]

    python检查文件更新失败_恢复自动更新/更新失败解决方法个人汇总[通俗易懂]步骤一:服务开启首先,打开任务管理器(快捷键Ctrl+shift+esc)(或者右键开始图标任务管理器(此方法只适应Win8Win10))(或者Ctrl+Alt+Del,点击任务管理器)打开服务选项卡+打开服务找到windowsupdate,右键,属性启动类型改为手动如果要关闭更新请改为禁用步骤二:组策略开启windows微标键+R键呼出【运行】2输入【gpedit.msc】组策略编辑器计算机配…

    2022年5月16日
    36
  • 常用方法在Ubuntu安装pycharm失败的解决方法[通俗易懂]

    常用方法在Ubuntu安装pycharm失败的解决方法[通俗易懂]按常用方法(下载安装包再./pycharm.sh)安装失败,报warn:keymap“visualstudio”notfound,keymap“eclipse”notfound想不通为什么和这些ide有关,查了也没解决最后直接到Ubuntu自带的Ubuntusoftware下搜索pycharm下载,一次成功,不知道为什么这么简单有效的方法大家都不优先推荐。。。…

    2026年4月16日
    4
  • vue 计数器_74161计数器

    vue 计数器_74161计数器计数器的实现在页面上简单实现一个计数器<!DOCTYPEhtml><htmllang="en"><head><metach

    2022年8月7日
    8
  • 三大(Chrome、Firefox、IE)webdriver下载地址

    三大(Chrome、Firefox、IE)webdriver下载地址目录三大浏览器webDriver下载地址三大浏览器webDriver下载地址webDriver下载地址。谷歌chromedriver下载地址:https://code.google.com/p/chromedriver/downloads/list火狐geckodriver下载地址:https://github.com/mozilla/geckodriver/releases/IEdriver下载地址:http://www.nuget.org/pa

    2025年12月7日
    30
  • python股票数据分析_用Python抓取新浪的股票数据「建议收藏」

    最近做数据分析,先是找到了Tushare这个免费开源的第三方财经包,但后来用了几天之后发现,它的日交易历史数据有时候有不准确的情况,查看源代码发现,这个包的数据源是凤凰财经,而对比凤凰网站其站点的数据本身就是有出入的,所以到也不是Tushare的问题。于是百度了一圈,发现很多网友都是获取新浪的股票数据,包括其历史数据和实时数据。于是乎试了一下,发现速度还挺快,没有具体去测时间但从感官上要比Tush…

    2022年4月7日
    176

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号