读取当前linux进程内存_(笔记)Linux上的内存分配

作者: LemonNan

原文: https://juejin.im/post/5ee3c34a518825430c3ad31d

前言

本篇是对Linux内存分配的一个学习笔记.

程序内存结构

下面是在 Linux/x86-32 中典型的一个进程内存结构

c20e9374e3f9956b4ad67b645d4b6c8e.png

  • 文本段包含了进程运行的程序机器语言指令. 文本段具有只读属性, 以防止进程通过勘误指针意外修改自身指令. 因为多个进程可以同时运行同一程序, 所以又将 文本段设为可共享 , 这样一份程序代码的拷贝可以映射到所有这些进程到虚拟地址空间中.

  • 初始化数据段包含显示初始化的全局变量和静态变量. 程序加载到内存时, 从可执行文件中读取这些变量的值.

  • 未初始化数据段包含了未进行显示初始化的全局变量和静态变量 . (书上写了一堆, 实际上就是懒加载)

  • 栈(stack)是一个动态增长和收缩的段, 由栈帧(stack frames)组成 . 系统会为每个当前调用的函数分配一个栈帧.栈帧中存储局部变量(所谓自动变量), 实参和返回值.

  • 堆(heap)时刻在运行时(为变量)动态进行内存分配的一块区域, 堆顶端称做 program break .

3g(32位)以上的虚拟内存地址, 程序无法访问.

程序的起始地址为 0x08048000 (32位)、0x00400000 (64位)

malloc 和 free

malloc

void *malloc(size_t size);
  • 栈向下增长超出之前曾达到的位置

  • 挡在堆中分配或者释放内存时, 通过调用 brk()、sbrk() 或 malloc 函数族来提升 program break 的位置.

  • 调用 shmat() 连接 System V 共享内存区或者当调用 shmdt() 脱离共享内存区时.

  • 调用 mmap() 创建内存映射或者 munmap() 解除内存映射

特点

  • malloc() 返回的内存快所采用的字节对齐的方式, 在大多数的硬件架构上, 意味着 malloc 是基于 8字节 或者 16字节 边界来分配内存的.

  • malloc 之后的内存, 在不使用的需要需要手动 free, malloc 和 free 一一对应, 否则可能会导致 未知错误(多次free) 或者 内存泄漏(没有调用free).

  • 允许分配小块内存

  • 允许随意释放内存快, 它们被维护于一张空闲内存列表中, 在后续内存分配调用时循环使用

free

free() 函数释放 ptr 参数所指向的内存快

void free(void *ptr);

特点

  • free 并不降低 program break 的位置, 而是将这块内存添加到空闲内存列表, 供后续的 malloc() 函数循环使用.这么做有几个原因:

    • 被释放的内存快通常位于堆的中间, 而非堆堆顶部, 因而降低 program break 不能达到效果

    • 最大限度减少程序必须执行 sbrk() 调用次数(减少系统调用的开销)

  • free 传入空指针不会做任何处理(从设计上来说这不是错误代码)

  • 调用 free 后堆参数 ptr 的使用, 比如再次调用 free, 会产生错误并且可能导致不可预知的结果.

为什么是8/16字节对齐

  • CPU 读取8字节对齐, 比如 double/long, 不对齐的话需要读写2次

  • CPU高速缓存行大小通常是 32 或者 64 字节. 如果对象是8字节对齐的数据, 则只需要占用一个缓存行, 如果不是8字节对齐的话, 则可能一部分数据在一个缓存行, 另一部分数据在其它的缓存行, 所以读写这个数据需要用到2个缓存行的数据而不是一个, 所有(目前1、2、3)级别的缓存都会受到此影响.

  • 对于在磁盘中的数据, 都是以512字节为最低的单位(一个扇区的数据大小), 如果是8字节对齐的话, 则数据会被存放在一个扇区里, 可以只通过一次读取将数据都读取出来, 如果数据不是8字节对齐, 则 数据可能会被存放到不同的扇区中, 并且还有可能不是相邻的扇区, 这就会 导致随机I/O , 降低数据处理的效率, 消耗更多的硬件资源. 对于上层来说, 数据是相连的(逻辑), 但是对于底层的物理硬件来说, 数据很有可能位于不相邻的扇区(数据处理最小单元).

so, 总结下来就是, 非对齐的数据访问 会因为增加硬件访问次数 比对齐的数据访问效率低.

说起缓存行, Java中有一些框架(比如Disruptor)考虑到了不同的CPU架构, 使用了CPU支持的缓存行填充, 以防止 伪共享(这里暂不做过多描述) 的发生从而降低效率.

通过 sysctl -a 查看

# 我的电脑中的数据hw.cachelinesize: 64hw.l1icachesize: 32768hw.l1dcachesize: 32768hw.l2cachesize: 262144hw.l3cachesize: 3145728

虚拟内存管理

内核为每一个进程都维护一张页表(page table) , 页表中的每个条目要么指出一个虚拟页面在 RAM 中的所在位置, 要么表明其当前驻留在磁盘上, 若进程访问的地址并无页表条目与之对应, 进程将会收到一个 SIGSEGV 信号.

Q: 虚拟页面的数据为什么会在磁盘上?

A: 每个程序中只有一部分 page 会驻留在 物理内存(RAM) 中, 未使用的 page 会被拷贝保存到交换区(swap area)内, 这是磁盘空间中的保留区域, 作为 RAM 的补充, 只有在需要的时候才会载入 物理内存.

进程在读取的时候, 如果访问的页面没有驻留在物理内存中, 将会发生页面错误(page fault), 内核即刻挂起的执行, 同时从磁盘中将该页面载入内存.

在 x86-32 中, page size 为 4096 字节(4KB), 一些其它的Linux使用的页面比 4096 字节更大.

Alpha 使用的 page size = 8192 字节(8KB), IA-64 的page size是可以改变的, 默认为 16384 字节.程序通过调用 sysconf(_SC_PAGESIZE) 获取系统虚拟内存的 page size.


虚拟内存的实现需要硬件中分页内存管理单元(PMMU)的支持, PMMU 把要访问的每个虚拟内存地址转换成相应的物理内存地址, 当特定虚拟内存地址所对应的页没有驻留于 RAM 中时, 将以页面错误(page fault)通知内核.

有效虚拟内存范围

由于 内核能为进程分配和释放页(和页表条目) , 所以进程的有效虚拟地址范围在其生命周期中可以发生变化. 如下场景会导致范围变化:

  • 栈向下增长超出之前曾达到的位置

  • 挡在堆中分配或者释放内存时, 通过调用 brk()、sbrk() 或 malloc 函数族来提升 program break 的位置.

  • 调用 shmat() 连接 System V 共享内存区或者当调用 shmdt() 脱离共享内存区时.

  • 调用 mmap() 创建内存映射或者 munmap() 解除内存映射

局部性原理

在计算机中大多数程序都有一个共同特点, 访问局部性 .

访问局部性包含两方面:

  • 空间局部性: 程序倾向于访问在最近访问过的内存地址附近的内存(由于指令是顺序执行的, 并且有时会按顺序处理数据结构)

  • 时间局部性: 这意味着数据被访问到, 在之后较短的时间内会被再次访问到(可能是由于循环)

优点

虚拟内存使得进程的虚拟地址空间和RAM的物理地址空间隔离开, 有以下一些好处

  • 进程与进程、进程与内核相互隔离, 所以一个进程不能读取其它进程或内核的内存, 因为每个进程的页表条目指向截然不同的物理内存地址.

  • 适当情况下, 多个进程鞥狗共享内存. 因为不同的进程页表条目可以指向相同的物理内存(RAM)地址.通常发生在如下的场景:

    • 执行同一程序的多个进程, 共享一份程序代码副本. 当多个进程执行相同的程序文件(或加载相同的共享库), 会隐式实现这一类型的共享.

    • 进程通过 shmget() 和 mmap() 系统调用显示请求与其它进程共享内存, 这样的目的是为了进程间的通信.

  • 实现保护机制: 相同的内存, 不同的进程可以设置不同的访问权限, 某些进程只读、某些拥有所有权限等.

  • 因为需要驻留在内存中的仅是程序的一部分, 所以程序的加载和运行都变快了, 而且一个程序所占用的大小(虚拟内存) 能够超出 RAM 容量.(因为有的事通过虚拟内存管理存放到了磁盘上)

一个进程所使用的RAM减少了, RAM中同时可容纳的进程数量增多. 这样的话加大了在任一时刻CPU可执行至少一个进程的概率, 这样往往也会提高CPU的利用率.

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

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

相关文章

php改成IP连接数据库,thinkphp,pdo连接数据库,host自动被替换成了本机ip

class DBAccess extends PDO{ private $charset; // 数据库字符集public $cacheDir_cache_$98sdf29fw!d#s4fef/; public $prename; public $time; function __construct($dsn, $user, $password){ try{ parent::__construct($dsn, $user, $pa…

django开源电子文档管理系统_「开源推荐」BookStack v2.8 发布,简洁美观的在线文档管理系统

程序介绍BookStack,基于 Mindoc、使用Go语言的Beego框架开发的功能类似GitBook和看云的在线文档管理系统,拥有简洁美观的页面布局,实现了文档采集、导入、电子书生成以及版本控制等强大的文档功能,并推出了配套的开源微信小程序 B…

python tcp通信如何实现多人聊天,Python实现多用户全双工聊天(一对一),python多用户,多用户全双工聊天简陋...

Python实现多用户全双工聊天(一对一),python多用户,多用户全双工聊天简陋多用户全双工聊天简陋版简单实现了两个客户端之间的通信,客户端发送消息,先由服务器接收,然后服务器转发到另一客户端。该版本功能非常简陋,仅仅…

matlab 随机森林算法_随机森林算法

随机森林是一种灵活,易于使用的机器学习算法,即使没有超参数调整,也能在大多数情况下产生出色的结果。它也是最常用的算法之一,因为它简单,并且可以用于分类和回归任务。在这篇文章中,您将学习随机森林算法…

python教程循环语句,Python基础教程之循环语句(for、while和嵌套循环)

循环可以用来重复执行某条语句,直到某个条件得到满足或遍历所有元素。1 for循环是for循环,可以把集合数据类型list、tuple、dict、set的元素遍历出来。(1)对list进行循环city_list [广州,深圳,东莞,佛山]city_list [广州,深圳,东莞,佛山]for city in c…

python课程的中期报告_电子课程设计中期报告

电子线路课程设计中期报告 电信工一班 王绪泉 200900121181 1. 设计题目 设计一个数字显示的电子温度计,要求包含模数转换模块,可数字显示,可测定温 度范围在 0 到 100 摄氏度之间,精度允许误差正负 0.5 摄氏度。 设计思路 本题目…

php-fpm 配置文件位置,php

先清空php-fpm.conf> /usr/local/php/etc/php-fpm.conf输入以下内容:[global]pid /usr/local/php/var/run/php-fpm.piderror_log /usr/local/php/var/log/php-fpm.log[www]listen /tmp/php-fcgi.sockuser php-fpmgroup php-fpmpm dynamicpm.max_children …

opengl 纹理贴到对应的位置_一步步学OpenGL(27) -《公告牌技术与几何着色器》

教程 27公告牌技术与几何着色器原文: http://ogldev.atspace.co.uk/www/tutorial27/tutorial27.htmlCSDN完整版专栏: https://blog.csdn.net/cordova/article/category/9266966背景从最初的一系列教程我们已经应用过了顶点着色器和片段着色器&#xff0c…

thinkphp如何通过php请求接口,thinkphp怎么做json数据接口

function checkUser(){//获取用户名 密码$uname$_GET[uname]; $upass$_GET[upass]; $userM("user");//访问数据库中的t_user表(t_ 以在config.php中设置为表前缀了)$where"uname".$uname." and upass".$upass."";//查询…

python 工资管理软件_基于[Python]的员工管理系统

基于[Python]的员工管理系统 ———————————————————————————————— 简介 使用python语言来完成一个员工管理系统,员工信息包含:员工工号,姓名, 年龄,性别,职位,工…

php执行zip压缩,PHP执行zip与rar解压缩方法实现代码

Zip:PclZip http://www.phpconcept.net/pclzip/index.en.phpRar:PECL rar http://pecl.php.net/package/rar以往过去要在php下执行解压缩程序,无非最常见的方法是写command 然后用exec()等执行函式去跑这在Windows下或许可以,但换…

python 当前目录_virtualenvwrapper打造多版本Python环境

前言面对多个 Python 开发项目时,需要针对不同的项目创建相应的开发环境。通常情况下,使用 virtualenv 创建一个虚拟的独立 Python 环境,但是 virtualenv 创建的环境相对分散不便于管理。这里推荐使用 virtualenvwrapper 来创建集中的便于管理…

oracle装了客户端怎么登陆账号,分享Oracle 11G Client 客户端安装步骤(图文详解)...

Oracle 11G Client 客户端安装步骤,具体如下:下载地址:http://www.gimoo.net/database/167737.html先将下载下来的ZIP文件解压,并运行setup.exe文件。执行到第四步之后,出现错误,直接点全部忽略就可以了。把…

python与excel互通_【python】python vs Excel ( 与mysql数据库之间的交互)

【python】python vs Excel ( 与mysql数据库之间的交互) 通过python与mysql数据库做交互 到目前为止大部分案例的演示数据都是基于文件进行读取的。那么python如何跟数据库之间做交互才是未来我们真正需要关心的。因为我们的数据最终还是要存储到数据库中去的。 python与数据库…

基于matlab的车牌识别系统程序,基于matlab的车牌识别系统的设计(附程序).doc

基于matlab的车牌识别系统的设计(附程序).doc 1车牌识别系统的设计1.摘要:汽车牌照自动识别系统是制约道路交通智能化的重要因素,包括车牌定位、字符分割和字符识别三个主要部分。本文首先确定车辆牌照在原始图像中的水平位置和垂直位置,从而定位车辆牌照…

python删除第一行_Python删除文件第一行

一、代码实例: def del_firstline(): for line in fileinput.input("file.txt", inplace 1): if not fileinput.isfirstline(): print(fileinput.replace("\n", "")) 二、使用的库:fileinput fileinput模块提供处理一个或…

weblogic 11g 配置oracle数据源 数据库驱动选哪个,weblogic11g配置db2数据源驱动有关问题...

weblogic11g配置db2数据源驱动问题今天在weblogic10.33上配置db2 9.7数据源,采用type4方式连接,驱动选择weblogic db2 type4驱动,配置成功后,开启应用测试,发现对元数据的获取存在问题,比如说通过 select *…

python英文词云代码_使用python实现个性化词云的方法

先上图片词云图 需要模板 pip install jieba pip install wordcloud 还需要安装另外两个东西这两个我也不太懂借鉴百度写上去的 pip install scipy pip install matplotlib 因为用ubuntu系统所有没有windows那么麻烦,也没有那么多报错 看到好多人制作自己的词云有没…

php 打开pdf文件附件,pdf里怎么链接到附件

首先试试修改config.inc.php 里的cookie前缀,随便改个试试,例如:$cookiepre FR4_; // cookie 前缀不行的话试试下面的,attachment.php找到function getlocalfile($filename, $readmod 1, $range 0) { if($readmod 1 || $readm…

python numpy库作用_python Numpy库

一.导入库 import numpy as np 二.创建 1.numpy中只有一种数据类型:ndarray,表示n维数组 创建ndarray数组: -由列表或者元组类型创建数组 -有元组类型创建数组 -创建特殊数组 2.采用np.array函数来创建,语法为: np.array(列表或元…