C_and_CPP 板


LINE

10. 不要在 stack 设置过大的变数以避免堆叠溢位(stack overflow) 由於编译器会自行决定 stack 的上限,某些预设是数 KB 或数十KB,当变数所需的空 间过大时,很容易造成 stack overflow,程式亦随之当掉(segmentation fault)。 可能造成堆叠溢位的原因包括递回太多次(多为程式设计缺陷), 或是在 stack 设置过大的变数。 错误例子: int array[10000000]; // 在stack宣告过大阵列 std::array<int, 10000000> myarray; //在stack宣告过大std::array 正确例子: C: int *array = (int*) malloc( 10000000*sizeof(int) ); C++: std::vector<int> v; v.resize(10000000); 说明:建议将使用空间较大的变数用malloc/new配置在 heap 上,由於此时 stack 上只需配置一个 int* 的空间指到在heap的该变数,可避免 stack overflow。 使用 heap 时,虽然整个 process 可用的空间是有限的,但采用动态抓取 的方式,new 无法配置时会丢出 std::bad_alloc 例外,malloc 无法配置 时会回传 null(注2),不会影响到正常使用下的程式功能 备注: 注1. 使用 heap 时,整个 process 可用的空间一样是有限的,若是需要频繁地 malloc / free 或 new / delete 较大的空间,需注意避免造成记忆体破碎 (memory fragmentation)。 注2. 由於Linux使用overcommit机制管理记忆体,malloc即使在记忆体不足时 仍然会回传非NULL的address,同样情形在Windows/Mac OS则会回传NULL (感谢 LiloHuang 补充) 补充资料: - https://zh.wikipedia.org/wiki/%E5%A0%86%E7%96%8A%E6%BA%A2%E4%BD%8D - http://stackoverflow.com/questions/3770457/what-is-memory-fragmentation - http://library.softwareverify.com/memory-fragmentation-your-worst-nightmare/ overcommit跟malloc: - http://goo.gl/V9krbB - http://goo.gl/5tCLQc --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 223.136.189.53
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1464012158.A.3DA.html
1F:推 LiloHuang: Linux 上 malloc 回传 non-NULL 不代表就是配置成功 05/23 22:20
2F:→ LiloHuang: 要留意预设的 optimistic memory allocation strategy 05/23 22:21
3F:推 kwpn: 若回传non-NULL但是是失败,要怎知道是失败,有error code吗 05/23 22:22
4F:→ LiloHuang: 有兴趣的可以看一下 Linux 文件 http://goo.gl/V9krbB 05/23 22:22
5F:→ LiloHuang: 没有办法知道,除非关掉 overcommit 的机制 (预设为开) 05/23 22:23
6F:→ wtchen: L大指的好像是realloc的情况?如果没有办法增加到想要 05/23 22:25
7F:→ LiloHuang: 再来一篇延伸阅读给有兴趣的 http://goo.gl/5tCLQc 05/23 22:25
8F:→ LiloHuang: 不单是 realloc,呼叫 malloc 几乎都会回传 non-NULL 05/23 22:25
9F:→ LiloHuang: 因为采用 overcommit 的机制,建议把延伸阅读看一下 05/23 22:26
10F:→ LiloHuang: 看过不少人以为 non-NULL 就是可以读写,其实不一定... 05/23 22:28
11F:→ wtchen: 这样如果出现memory frag.不是很难debug吗? 05/23 22:29
12F:推 LiloHuang: overcommit 某种程度可以让系统有效的利用实体记忆体 05/23 22:32
13F:→ wtchen: kernel没有限制user space使用memory的上限? 05/23 22:38
14F:→ LiloHuang: 这是两件事情,单一 process 是否达到上限,跟一堆 05/23 22:40
15F:→ wtchen: 刚刚查了一下,Windows好像也有overcommit? 05/23 22:40
16F:→ wtchen: 所以windows会有同样的问题吗? 05/23 22:41
17F:→ LiloHuang: processes 配置了 1GB ,但是却没办法正常存取是两件事 05/23 22:41
18F:→ LiloHuang: Windows / Mac OS X 在记忆体不够用时,皆会回传 NULL 05/23 22:42
※ 编辑: wtchen (223.136.189.53), 05/23/2016 23:02:14
19F:→ tinlans: 标题杀人 被标题骗到很生气地进来看 XD 05/25 12:02
抱歉造成误解.... ※ 编辑: wtchen (220.128.143.228), 05/25/2016 12:53:42
20F:推 hylkevin: linux会在需要实体记忆体时触发swap或oom,所以顶多有 05/27 17:32
21F:→ hylkevin: 效能问题,应该不至於会error。 05/27 17:32
22F:推 LiloHuang: 不够用就是会被 OOM killer 给砍掉... 不是无上限的 05/27 18:52
23F:→ LiloHuang: #include <cstdlib> 05/27 18:58
24F:→ LiloHuang: #include <cstring> 05/27 18:58
25F:→ LiloHuang: int main() { 05/27 18:59
26F:→ LiloHuang: const size_t CHUNK_SIZE = 1024*1024*1024; 05/27 18:59
27F:→ LiloHuang: const size_t NUMBER_OF_CHUNK = 1024; 05/27 18:59
28F:→ LiloHuang: void *chunks[NUMBER_OF_CHUNK]; 05/27 18:59
29F:→ LiloHuang: // allocate without mapping 05/27 18:59
30F:→ LiloHuang: for (size_t i=0; i<NUMBER_OF_CHUNK; i++) { 05/27 18:59
31F:→ LiloHuang: chunks[i] = malloc(CHUNK_SIZE); 05/27 19:00
32F:→ LiloHuang: } 05/27 19:00
33F:→ LiloHuang: // use memset to map physical memory 05/27 19:00
34F:→ LiloHuang: for (size_t i=0; i<NUMBER_OF_CHUNK; i++) { 05/27 19:00
35F:→ LiloHuang: memset(chunks[i], 0x0, CHUNK_SIZE); 05/27 19:00
36F:→ LiloHuang: } 05/27 19:00
37F:→ LiloHuang: // reclaim allocated chunks 05/27 19:00
38F:→ LiloHuang: for (size_t i=0; i<NUMBER_OF_CHUNK; i++) { 05/27 19:01
39F:→ LiloHuang: free(chunks[i]); 05/27 19:01
40F:→ LiloHuang: } 05/27 19:01
41F:→ LiloHuang: return 0; 05/27 19:01
42F:→ LiloHuang: } 05/27 19:01
43F:→ LiloHuang: 有兴趣的自己跑跑看上面,看会不会被 OOM killer 砍掉 05/27 19:02
44F:→ LiloHuang: 顺便检查一下 malloc 的回传值,是否都是 non-NULL 05/27 19:04
45F:→ LiloHuang: 加个 if (!chunks[i]) throw std::bad_alloc(); 之类的 05/27 19:07
46F:→ LiloHuang: 看到底是 OOM killer 砍掉还是 NULL dereference 挂掉 05/27 19:08
47F:→ LiloHuang: 这三个回圈一定要分开跑,写成一个回圈就不一定会被砍 05/27 19:09
48F:→ wtchen: OOM不会选择砍别的process吗?如果在preempt RT kernel 05/27 19:16
49F:→ wtchen: 的话加上mlockall就会砍别的process吧? 05/27 19:16
50F:推 LiloHuang: 有评分机制,可参考 oom_kill.c https://goo.gl/vVqyeo 05/27 19:18
51F:→ LiloHuang: 有可能别的 process 会被砍,假设它 oom_score 更高 05/27 19:20
52F:→ LiloHuang: 只是上面的范例,通常会是被砍的那一个... :) 05/27 19:20
53F:→ wtchen: 要写的文章又多一篇 XD 05/27 20:32







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Boy-Girl站内搜寻

TOP