Linux 多线程程序虚拟内存占用过大有什么问题吗?

2016-10-09 11:40:21 +08:00
 algas
最近写了一个程序,总是在计算规模比较大的时候异常退出
[1] 47393 segmentation fault ./a.out 300 0.5

发现退出总是发生在启动多线程的部分,多线程部不需要额外申请内存。
在退出发生前,我观察到系统程序虚拟内存比较高, RSS ~ 80G , VSZ ~ 135G 。
机器只有 128G 物理内存,没有分配 swap 分区和文件, VSZ 明显超过了物理内存,不知道是不是因为这个原因导致程序退出的,求指点。


> ulimit -a

-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) unlimited
-c: core file size (blocks) 0
-m: resident set size (kbytes) unlimited
-u: processes 515250
-n: file descriptors 1024
-l: locked-in-memory size (kbytes) 64
-v: address space (kbytes) unlimited
-x: file locks unlimited
-i: pending signals 515250
-q: bytes in POSIX msg queues 819200
-e: max nice 0
-r: max rt priority 0
-N 15: unlimited
11769 次点击
所在节点    Linux
43 条回复
ryd994
2016-10-10 12:25:47 +08:00
@algas mmap 不是用来分配内存的啊……… map 文件………
内存管理算法一般都不能很好的处理特大段内存分配,真的没有办法拆么?
我是学材料工程和计算机双专业,所以计算物理这边多少沾得上
ryd994
2016-10-10 12:49:44 +08:00
@algas 你这样写
size_t N = 220 * 220;
size_t 用于表示内存范围的时候不可能溢出,否则就违背定义了。如果我没有记错,在 64 位系统上是 unsigned long long

你的问题是: int 只有 32767 的上限, 220*220=4e4 明显超了,后面 N * N * sizeof(double) 里 N*N 先计算得中间结果,中间结果 promote 为 size_t 与 double 大小相乘后作为 malloc 的参数。第一步时,因为双方都是 int ,所以没有范围调整,所以这里也超了。

重申: size_t 不是 uint16 ,是 uint64 ,如果 size_t 溢出,则当前平台上根本不可能对该内存空间寻址,换言之根本不存在 size_t 溢出而其他方法能正常分配内存的情况。
algas
2016-10-15 09:45:44 +08:00
@ryd994 你说的是对的,我之前看了以下 size_t 的类型,就没有管是不是 64 位的 unsigned 。
不过我这里 int 是 32 位的。
sizeof(int) = 4.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/311331

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX