java进程内存一直没释放_五分钟彻底搞懂你一直没明白的Linux内存管理

现在的服务器大部分都是运行在Linux上面的,所以,作为一个程序员有必要简单地了解一下系统是如何运行的。对于内存部分需要知道:

  1. 地址映射
  2. 内存管理的方式
  3. 缺页异常

先来看一些基本的知识,在进程看来,内存分为内核态和用户态两部分,经典比例如下:

dffc5f956f8ac528a132004fc3a441a7.png

从用户态到内核态一般通过系统调用、中断来实现。用户态的内存被划分为不同的区域用于不同的目的:

981a9cc8fe1c7d01649a536f424747cd.png

当然内核态也不会无差别地使用,所以,其划分如下:

f240d9c021d0d96b9258c042ad4f45dd.png

下面来仔细看这些内存是如何管理的。

地址

在Linux内部的地址的映射过程为逻辑地址–>线性地址–>物理地址,物理地址最简单:地址总线中传输的数字信号,而线性地址和逻辑地址所表示的则是一种转换规则,线性地址规则如下:

bf559707131b3115cd74674412080b6b.png

这部分由MMU完成,其中涉及到主要的寄存器有CR0、CR3。机器指令中出现的是逻辑地址,逻辑地址规则如下:

f5edd031fda7a411e737e93490fbad7b.png

在Linux中的逻辑地址等于线性地址,也就是说Inter为了兼容把事情搞得很复杂,Linux简化顺便偷个懒。

内存管理的方式

在系统boot的时候会去探测内存的大小和情况,在建立复杂的结构之前,需要用一个简单的方式来管理这些内存,这就是bootmem,简单来说就是位图,不过其中也有一些优化的思路。

bootmem再怎么优化,效率都不高,在要分配内存的时候毕竟是要去遍历,buddy系统刚好能解决这个问题:在内部保存一些2的幂次大小的空闲内存片段,如果要分配3page,去4page的列表里面取一个,分配3个之后将剩下的1个放回去,内存释放的过程刚好是一个逆过程。用一个图来表示:

bbfa5f7d24cd1ca0738f5f947eb8a34d.png

可以看到0、4、5、6、7都是正在使用的,那么,1、2被释放的时候,他们会合并吗?

static inline unsigned long
__find_buddy_index(unsigned long page_idx, unsigned int order)
{
return page_idx ^ (1 << order);// 更新最高位,0~1互换
}

从上面这段代码中可以看到,0、1是buddy,2、3是buddy,虽然1、2相邻,但他们不是。内存碎片是系统运行的大敌,伙伴系统机制可以在一定程度上防止碎片~~另外,我们可以通过cat /proc/buddyinfo获取到各order中的空闲的页面数。

伙伴系统每次分配内存都是以页(4KB)为单位的,但系统运行的时候使用的绝大部分的数据结构都是很小的,为一个小对象分配4KB显然是不划算了。Linux中使用slab来解决小对象的分配:

dae1d1071a2f4a359a40524c6be1577d.png

在运行时,slab向buddy“批发”一些内存,加工切块以后“散卖”出去。随着大规模多处理器系统和NUMA系统的广泛应用,slab终于暴露出不足:

  1. 复杂的队列管理
  2. 管理数据和队列存储开销较大
  3. 长时间运行partial队列可能会非常长
  4. 对NUMA支持非常复杂

为了解决这些高手们开发了slub:改造page结构来削减slab管理结构的开销、每个CPU都有一个本地活动的slab(kmem_cache_cpu)等。对于小型的嵌入式系统存在一个slab模拟层slob,在这种系统中它更有优势。

小内存的问题算是解决了,但还有一个大内存的问题:用伙伴系统分配10 x 4KB的数据时,会去16 x 4KB的空闲列表里面去找(这样得到的物理内存是连续的),但很有可能系统里面有内存,但是伙伴系统分配不出来,因为他们被分割成小的片段。那么,vmalloc就是要用这些碎片来拼凑出一个大内存,相当于收集一些“边角料”,组装成一个成品后“出售”:

bfe5e364c350c7174ad7d54d4a6c6c43.png

之前的内存都是直接映射的,第一次感觉到页式管理的存在:D 另外对于高端内存,提供了kmap方法为page分配一个线性地址。

进程由不同长度的段组成:代码段、动态库的代码、全局变量和动态产生数据的堆、栈等,在Linux中为每个进程管理了一套虚拟地址空间:

9920d2d184413602ffcbbd09f71eed24.png

在我们写代码malloc完以后,并没有马上占用那么大的物理内存,而仅仅是维护上面的虚拟地址空间而已,只有在真正需要的时候才分配物理内存,这就是COW(COPY-ON-WRITE:写时复制)技术,而物理分配的过程就是最复杂的缺页异常处理环节了,下面来看!

缺页异常

在实际需要某个虚拟内存区域的数据之前,和物理内存之间的映射关系不会建立。如果进程访问的虚拟地址空间部分尚未与页帧关联,处理器自动引发一个缺页异常。在内核处理缺页异常时可以拿到的信息如下:

  1. cr2:访问到线性地址
  2. err_code:异常发生时由控制单元压入栈中,表示发生异常的原因
  3. regs:发生异常时寄存器的值

处理的流程如下:

e9429fe1561c1361d265277dae642b15.png

发生缺页异常的时候,可能因为不常使用而被swap到磁盘上了,swap相关的命令如下:

bf4b151cd8c0e96afeabeaf8bd218c5f.png

如果内存是mmap映射到内存中的,那么在读、写对应内存的时候也会产生缺页异常。

来源:WsztRush
链接:http://wsztrush.github.io/%E7%BC%96%E7%A8%8B%E6%8A%80%E6%9C%AF/2015/05/13/Linux-Memory.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/506310.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ehcache使用_Mybatis整合(Redis、Ehcache)实现二级缓存,恕我直言,你不会

目的&#xff1a;Mybatis整合Ehcache实现二级缓存Mybatis整合Redis实现二级缓存Mybatis整合ehcache实现二级缓存ssm中整合ehcache在POM中导入相关依赖org.springframework spring-context-support ${spring.version}org.mybatis.caches mybatis-ehcache 1.1.0net.s…

取证 c语言实现日志导出_日志与日志不一样:五种不能忽略的日志源

给日志源分出主次大有利于开展有效事件响应。就像分诊护士一样&#xff0c;安全人员也必须给数据分出个优先主次&#xff0c;以帮助他们更好地识别问题&#xff0c;使公司企业及其数据和设备能够避免入侵者和网络攻击的伤害。但是&#xff0c;记录和监视IT环境中的所有相关事件…

codesoft指定打印机打印_巧用win32print来控制windows系统打印机并推送打印任务

小爬最近接到的一个需求是&#xff1a;将windows系统下的打印任务批量有序传输给网络打印机&#xff0c;实现批量有序打印。用户先从公司的OA(B/S模式)系统下 打印指定内容的表单以及表单中的附件内容。这个问题可以这样分解&#xff1a;1、抓包&#xff0c;得到OA对应的任务接…

crmeb pc端模板下载_PC端人人影视下载速度如何提高

首先下载最新版本的人人影视我的是这个&#xff0c;右下角版本号1022然后在下载设置那里把连接数调高一点大致就这样我的就是调了一下然后下载速度高了许多&#xff0c;刚开始只有1M左右的速度&#xff0c;现在4&#xff0c;5M每秒

android 编辑自定义可编辑表格,smart 框架 列表 可编辑表格

可编辑表格常用属性colModel: [{label: "主键ID", name: "hellop1",hidden:true},{label: "列明", name: "hellop2",align: "center", editable: true, edittype: text, editrules: { required: true } }editable&#xff1…

dos虚拟机如何全屏显示_实用工具 | 虚拟机软件VirtualBox详细使用介绍

前言&#xff1a;搞自动化控制的工程师&#xff0c;要擅于利用工具和软件&#xff0c;其中&#xff0c;虚拟机就是很好的工具&#xff0c;安装操作系统以后&#xff0c;就相当于多了一台电脑&#xff0c;可以用来测试网络&#xff0c;测试软件&#xff0c;或者直接用来调试设备…

axure原型案例_Axure RP9原型案例:制作一个可以滑动的菜单

摘要&#xff1a;在PC端的产品中我们会常常见到滑动式菜单&#xff0c;当鼠标移入菜单上方&#xff0c;向下或向右自动滑动弹出子菜单&#xff0c;当页面信息层级较多或功能较多时&#xff0c;在产品设计时经常会用到这种滑动式菜单。今天就和大家分享如下制作滑动式菜单的交互…

一会404一会500_没网络就是404?这锅可不能乱背!

在那个房价未突破天际&#xff0c;一台计算机还可以占着几间房的年代。数据库被存放在一个神秘的房间中。如果无法找到请求者所需要的文件&#xff0c;用户将会得到file not found的信息。而这件房间的门牌就是404。404https://www.zhihu.com/video/1168484640850579456当然以上…

android8 呼吸灯,红米note8pro呼吸灯颜色如何设置?

红米note8pro支持呼吸灯功能&#xff0c;当有未读通知的时候&#xff0c;指示灯就会闪烁提醒。此外&#xff0c;我们还可以根据自己的喜好设置呼吸灯的颜色&#xff0c;下面为大家带来详细的设置教程。红米note8pro怎么设置呼吸灯颜色1、首先&#xff0c;进入手机桌面&#xff…

java string 返回匹配正则的字符串的起始位置_【Python】正则表达式

概述正则表达式是一个特殊的字符序列&#xff0c;它能帮助你方便的检查一个字符串是否与某种模式匹配。 Python 自1.5版本起增加了re 模块&#xff0c;它提供 Perl 风格的正则表达式模式。re 模块使 Python 语言拥有全部的正则表达式功能。 compile 函数根据一个模式字符串和可…

html九图拼图游戏代码,HTML5拼图游戏

拼图游戏介绍 拼图游戏将一幅图片分割成若干拼块并将它们随机打乱顺序。当将所有拼块都放回原位置时&#xff0c;就完成了拼图(游戏结束)。 在“游戏”中&#xff0c;单击滑块选择游戏难易&#xff0c;“容易”为3行3列拼图游戏&#xff0c;中间为一个4行4列拼图游戏&#xff0…

access驱动程序_Linux驱动程序学习二 (续) scull 源码在内核5.4.0上的编译调试

《LINUX设备驱动程序》第三章提供了源码scull,但是由于我用的是5.4.0内核,书中的是2.6.10内核,内核发生了很大的变化,因此编译scull源码花费了不少时间,下面是编译调试记录。&#xff08;这个编译调试记录应该是目前网络上适应内核版本最高的&#xff0c;所以也希望给近期加入《…

android评论嵌套,android 嵌套的listview示例(可参照实现朋友圈评论)

android 嵌套的listview示例(可参考实现朋友圈评论) 最近在项目中用到listview中再嵌套一个listview&#xff0c;两层也有监听&#xff0c;都没有问题。其实&#xff0c;主要解决里面那一层的listview的高度计算就可以&#xff0c;外面那一层listview自动计算。加上里面那层展开…

捷达vs7测试_捷达VS5话题:防撞钢梁,溃缩梁。第200311期

//封面图&#xff0c;捷达VS5&#xff0c;自中&#xff0c;最近看到网上有些观点有点儿带偏&#xff0c;然后咱们技术群今天也讨论了一下&#xff0c;大家也来听听咱们爱折腾的车主们是怎么看防撞梁的事情的。事情起因是因为大家看到一些网上的拆车视频&#xff0c;说捷达VS5前…

html5 原生拖拽,原生JS实现拖拽效果

这篇文章主要为大家详细介绍了原生JS实现拖拽效果&#xff0c;文中示例代码介绍的非常详细&#xff0c;具有一定的参考价值&#xff0c;感兴趣的小伙伴们可以参考一下本文实例为大家分享了JS实现拖拽效果的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下想要让整个元…

ov5640帧率配置_逃离塔科夫怎么提升帧率 帧率优化建议_单机游戏_游戏攻略

逃离塔科夫有着非常真实的游玩与画面表现&#xff0c;所以这类的多人游戏比较吃配置&#xff0c;那么帧率上不去会十分影响游戏体验&#xff0c;下面请看由“SIIYAM”带来的逃离塔科夫帧率优化建议&#xff0c;一起来看看吧。帧率优化建议&#xff1a;这游戏对于cpu资源分配和内…

js 带笔锋 签字版_年轻人的第一支签字笔? ——米家签字笔评测

emm感觉笔者能咕到自己都怀疑人生惹QAQ…对于小米而言&#xff0c;可能他家中性笔做的还真没手机那么好。但对于劝退这件事&#xff0c;理由其实是很复杂的。但既然决定了要来写这样一点东西&#xff0c;那我也自然要把我知道的和能想到的&#xff0c;略述一二。我们先来看看小…

itools 不支持缩略图下载_PS插件缩略图3.8.0.96安装教程

插件下载[名称]&#xff1a;PS插件『缩略图补丁3.8.0.96』[大小]&#xff1a;1.4 MB [语言]&#xff1a;简体中文 [安装环境]&#xff1a;Win7/Win8/Win10[支持版本]&#xff1a;PS CS6—CC2019[32/64位下载链接]&#xff1a;https://pan.baidu.com/s/1AlOlWzMZfYgdJSlZpbQsmw…

z370支持pcie信号拆分吗_定了!AMD B550主板确认将支持PCIE4.0,多项能力接近X570

近日&#xff0c;华擎B550AM Gaming主板照片和文档泄露&#xff0c;Micro-ATX板型、具备4内存插槽&#xff0c;支持PCIE4.0显卡/固态硬盘。B550芯片组本身无法拆分PCIE4.0信道&#xff0c;所以华擎的这张B550主板在搭配第三代锐龙时只有第一条PCIE插槽(通常安装独立显卡)和M.2固…

mac 修改conda镜像 condarc_win10 修改anaconda源

通过 conda config 命令生成配置文件&#xff0c;这里&#xff0c;我们使用清华的镜像&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/&#xff0c;首先&#xff0c;打开CMD&#xff0c;执行命令&#xff1a;conda config --add channels https://mirro…