hi扩关车来啦!
车主@Cheese1008 随缘月 属性置顶

副驾@Capsicol944 随缘月 有图!!!

@·瑶瑶不爱吃香菜· 属性翟潇闻朴彩英
✨ @摘星闻呓 随缘约约iping
@熊耶雾也浓 随缘️️,属性置顶,爱互动的宝宝来找我丸![赢牛奶]
@·桃椰奶闻· 随缘约约iping[开学季]
@翟潇闻一定会暴富的 原ID夏日恋闻记,扩毒唯
@星湾灰岛 随缘约
@·樱岛颂枳· 随缘月月 自己壁垒
@星雾共感· 翟潇闻朱志鑫
@·被外星人抓走啦 ️️翟潇闻毒唯

—落魄的歌唱家—留备注—
-福建不知名小美女
-小妮

中考生不怎么看微博
-原ID:浪漫为妮永存(第一个ID)
-birthday:2007.01.13/2006.11.25
-目标:中国音乐学院
-是个搞笑女会酸人也会阴阳 茶艺top
-四肢健全五官齐全是个人
-性格就是懒 兴趣就是玩 特长就是吃 技能就是睡
-雷点无所谓你踩了我再告诉你事不过三就ok
-怎样活都行 幸福就行 少点坎坷就行

【关于内存管理:争议很大的问题】

文 | 小林coding

出品 | 小林coding(ID:CodingLin )

已获得原公众号的授权转载

早上看到读者在群里讨论这些面试题(下图1):

其中,第一个问题「在 4GB 物理内存的机器上,申请 8G 内存会怎么样?」存在比较大的争议,有人说会申请失败,有的人说可以申请成功。

这个问题在没有前置条件下,就说出答案就是耍流氓。因为在 32 位操作系统和 64 位操作系统场景下,答案是不同的。

另外,我们还要看申请完 8G 内存后会不会被使用,会被使用是一种情况,不会被使用又是另外一种情况了。

所以,我们要分场景讨论。

正文
应用程序通过 malloc 函数申请内存的时候,实际上申请的是虚拟内存,此时并不会分配物理内存。

当应用程序读写了这块虚拟内存,CPU 就会去访问这个虚拟内存, 这时会发现这个虚拟内存没有映射到物理内存, CPU 就会产生缺页中断,进程会从用户态切换到内核态,并将缺页中断交给内核的 Page Fault Handler (缺页中断函数)处理。

缺页中断处理函数会看是否有空闲的物理内存:

如果有,就直接分配物理内存,并建立虚拟内存与物理内存之间的映射关系。
如果没有空闲的物理内存,那么内核就会开始进行回收内存的工作,如果回收内存工作结束后,空闲的物理内存仍然无法满足此次物理内存的申请,那么内核就会放最后的大招了触发 OOM (Out of Memory)机制。
32 位操作系统和 64 位操作系统的虚拟地址空间大小是不同的,在 Linux 操作系统中,虚拟地址空间的内部又被分为内核空间和用户空间两部分,如下所示:

通过这里可以看出:

32 位系统的内核空间占用 1G,位于最高处,剩下的 3G 是用户空间;
64 位系统的内核空间和用户空间都是 128T,分别占据整个内存空间的最高和最低处,剩下的中间部分是未定义的。
现在可以回答这个问题了:在 32 位操作系统、4GB 物理内存的机器上,申请 8GB 内存,会怎么样?

因为 32 位操作系统,进程最多只能申请 3 GB 大小的虚拟内存空间,所以进程申请 8GB 内存,在申请虚拟内存阶段就会失败(我手上没有 32 位操作系统测试,我估计失败的原因是 OOM)。

在 64 位操作系统、4GB 物理内存的机器上,申请 8G 内存,会怎么样?

64 位操作系统,进程可以使用 128 TB 大小的虚拟内存空间,所以进程申请 8GB 内存是没问题的,因为进程申请内存是申请虚拟内存,只要不读写这个虚拟内存,操作系统就不会分配物理内存。

我们可以简单做个测试,我的服务器是 64 位操作系统,但是物理内存只有 2 GB。
图2

现在,我在机器上,申请 4 GB 内存,注意下面代码只是单纯分配了虚拟内存,并没有使用该虚拟内存:

#include
#include
#include
#include
#include

int main() {

int ret;

char* addr[4];

printf("使用cat /proc/%d/maps查看内存分配\n",getpid());

size_t s = 1024 * 1024 * 1024;

int i = 0;

for(i = 0; i < 4; ++i) {

printf("alloc size = %d\n", s);

addr[i] = (char*) malloc(s);

printf("主线程调用malloc后,申请1gb大小得内存,此内存起始地址:0X%x\n", addr[i]);

}

getchar();

return 0;
}
然后运行这个代码,可以看到,我的物理内存虽然只有 2GB,但是程序正常分配了 4GB 大小的虚拟内存:


我们可以通过下面这条命令查看进程的虚拟内存大小:

# ps aux | grep alloc_4g
USER

PID %CPU %MEM

VSZ

RSS TTY

STAT START

TIME COMMAND
root

7797 0.0 0.0 4198540 352 pts/1

S+

16:58

0:00 ./alloc_4g
其中,VSZ 就代表进程使用的虚拟内存大小,RSS 代表进程使用的物理内存大小。可以看到,VSZ 大小为 4198540,也就是 4GB 的虚拟内存。

然后,我们改一下代码,在申请完虚拟内存后,通过 memset 函数使用这个虚拟内存,看看会发生什么。

#include
#include
#include
#include
#include

int main() {

int ret;

char* addr[4];

printf("使用cat /proc/%d/maps查看内存分配\n",getpid());

size_t s = 1024 * 1024 * 1024;

int i = 0;

for(i = 0; i < 4; ++i) {

printf("alloc size = %d\n", s);

addr[i] = (char*) malloc(s);

printf("主线程调用malloc后,申请1gb大小得内存,此内存起始地址:0X%x\n", addr[i]);

//访问虚拟内存

memset(addr[i], 0, s);

}

getchar();

return 0;
}
运行结果:

图4

可以看到,在申请了 2GB 虚拟内存后,然后马上使用了这块虚拟内存,由于这台机器的物理内存只有 2 GB,所以发生了 OOM。

至此, 验证完成了。简单总结下:

在 32 位操作系统,因为进程最大只能申请 3 GB 大小的虚拟内存,所以直接申请 8G 内存,会申请失败。
在 64位 位操作系统,因为进程最大只能申请 128 TB 大小的虚拟内存,即使物理内存只有 4GB,申请 8G 内存也是没问题,因为申请的内存是虚拟内存,等这块虚拟内存被访问了,因为物理空间不够,就会发生 OOM。

https://t.cn/A6XkOzhh

namo-amitabhaya!


发布     👍 0 举报 写留言 🖊   
✋热门推荐
  • 当初2.7W的绿城凤栖鹭鸣,大家都是嫌贵的,现在难道就值得了?第二是当前楼市进入了400万段位的顺销阶段,天府养云肯定是会顺销的,包括其他一些一旦上到400万就
  • 今日的中国社会已不是一张大学文凭就能骗得饭吃的了,拿了文凭而找不着工作的人们,应该要自己反省:社会需要的是人才、是本事、是学问,而我自己究竟是不是人才,有没有本
  • 记录日落的话,可以和你一样浪漫吗张小茄在快下班的时候微信和我说她想吃小蛋糕和虫子面包,她知道我公司附近有一个味多美,意思是让我给她买。后来见我生气了,说“我就要
  • ”9⃣️突然想起来我还有一个想说的,就是我跟这个神父聊天的时候,他总是在我说出一些词的时候表达出或者露出“你连这个词都知道啊?神父和我房东都看过很多他的书,就想
  • 海螺里经常会混着寄居蟹,小时候会蹲在礁子上看他们爬看好久游泳的时候有时能遇见水母,后来才知道它和大人说的海蜇貌似是一个东西,看海边有人抓过捧到岸上不一会就化了#
  • 那句"你是我提心吊胆的春天"我理解为我的心永远都在为你跳动,我非常爱你,综合拉姐所有的发言为什么会有人理解为想要一个肯定的答案,以后会分手呢
  • 例如,今天,我就在某售楼部,遇见了我想见的江南​(姐就是有化腐朽为神奇的能力,吹咩)#良辰好景知几何[超话]# 真想给粽子姐一巴掌,原来乔江是这女二给叫上来了,
  • 如果你不得不让别人接受你的建议并认为你的建议是正确的,那么唯一的办法就是去他那里呆一个月。 #养狗必备的东西# #微博云上新#首先发的是狗狗用品:狗玩具,牵引
  • #领养代替购买# 爆炸新闻经常购物的,逛淘宝,游京东,天猫网上购物的兄弟姐妹们,你们的福利来了,你买的商品只要是在淘宝京东天猫都可以返现,自己买省钱,分享还能赚
  • 记者:“您总说你心中理想的教练是埃里克森和博斯科夫的混合体,如今你在意甲见过一个这样的教练吗?”曼奇尼:“我发现这是一种完美的混合,因为我跟这种混合正好相反:在
  • 人与人之间不总是和谐,但也绝不是永远对立,试着去放下心中的怨和恨,因为人生苦短,每个人都不容易,有交集才会精彩。有时候我总是不知道该怎么表达我对你的感觉 说我爱
  • 오빵.. ❤내 첫 사랑 ❤너무 멋진 내 오빠 ❤나의 달콤한 사랑 ❤인생의 기적 ❤✨나의 잘 생긴 왕자 ❤우리의 축복 ❤우리 나라의 자존심 ❤국가
  • #大白和小范# 是和大白的第二个生日这周经常吵架呀 然后一见面 我就不和他说话后来他就在旁边问我要去哪里 我就自己走不理他 后来他就说你知道你来姨妈嘛 穿这么少
  • 还是想问为什么会被他在路上叫住,是因为我看起来好骗吗[疑问] 我就当是一次奇妙的经历(一这么想就觉得还是被骗了 一认为被骗就觉得我还是听到了一些) 其实可能是因
  • 也居然有人用记事本写那么多日记,蹦出来的字像是不说停就可以永远写下去;木子在机缘巧合拥有了微博之后成为了我的“定心丸”焦虑的时候溜到她微博看一眼,各种大部头的读
  • 当当:#严浩翔[超话]##严浩翔 音轨成诗十八拍##严浩翔十八岁生日快乐# 在我印象中你还是那个十七,六岁的小团子,怎么就突然18了呢?这是我陪你过的第二个生
  • 他强调,要牢固树立以人民为中心的发展理念,始终保持“时时放心不下”的责任感,以“钉钉子”的精神抓落实、抓推进、抓督查,全力以赴推进全国文明城市创建工作,统筹做好
  • 打车回家的路上,一个中东的司机用并不太利索的英文给我聊着天。我很惊奇他有这样的观点,也在后面的聊天里确信他也不是为了迎合我而说的。
  • 后来快毕业的时候,我才把小狗带回家,告诉家里这个是我的小兔子。放生小狗=放生我的钱我爸妈其实也没有很讨厌小动物,只是觉得要养很麻烦,所以我自己能照顾的话他们就没
  • 昨天,隔了半个月…她想起来了…问我没给是不是不好,说实话我都忘了…我也没想到她真没给啊☹️我是小助理吗还得我提醒!我从来都没说我不随……我到现在也是?