在基于UNIX的操作系统上运行的C ++程序通常分配的初始堆大小是多少?
如果g ++编译器完全决定它在这方面有什么作用?
答案 0 :(得分:5)
对于C ++,无论平台是什么,通过根据需要向操作系统请求更多内存,堆几乎总是动态扩展。在某些嵌入式平台或某些非常旧的平台上,这可能不是真的,但是由于环境的性质,你可能非常清楚你有多少堆。
在Unix平台上,这是双重的。即便是大多数Unix嵌入式平台都以这种方式工作。
在这样工作的平台上,库通常没有任何内部限制,而是依赖操作系统告诉它它不能再有内存。实际上,由于各种原因,您实际上要求的内存超过可用内存时,可能会发生这种情况。
在大多数Unix系统上,进程可以拥有的内存总量存在硬性限制。可以使用getrlimit
系统调用查询此限制。相关常数是RLIMIT_AS。此限制控制可分配给进程的最大内存页数,并直接限制可用的堆空间量。
不幸的是,这个限制没有直接说明你可以使用多少堆。内存页面作为mmap调用的结果分配给进程,用于保存程序代码本身,以及进程的堆栈。
此外,如果将物理内存和交换空间加在一起,此限制通常会设置得超过整个系统可用的总内存。所以实际上你的程序在达到这个限制之前会经常耗尽内存。
最后,某些版本的Unix过度分配页面。它们允许您分配大量页面,但实际上只有在您写入页面时才能找到这些页面的内存。这意味着即使所有内存分配调用都成功,您的程序也可能因内存不足而被终止。这个的基本原理是能够分配只能部分使用的巨大数组。
因此,简而言之,没有一个典型的尺寸,也没有好的方法来确定它的大小。
答案 1 :(得分:4)
通过根据需要向操作系统请求更多内存来动态扩展堆。
完全不是由编译器确定,而是由库确定。
使用GC修复动态语言中堆的大小更为常见。在C和C ++中,要求操作系统获得更多内存是一件简单的事情,因为在您需要它时它是显而易见的。因此,初始堆大小非常重要,只是分配库的一个实现决策。
答案 2 :(得分:0)
简而言之,没有明确的配置堆大小的方法。但是我们确实有一些方法可以影响堆内存大小,因为堆内存大小是总可用内存的一部分。
您可以通过以下方式获取系统中可用内存的总量:
cat /proc/meminfo | grep CommitLimit
CommitLimit: 498080 kB
此CommitLimit
计算如下公式:
CommitLimit = ('vm.overcommit_ratio' * Physical RAM) + Swap
假设交换为零,通过设置overcommit_ratio
,您可以配置总可用内存。您可以设置overcommit_ratio by
:
sysctl -w vm.overcommit_ratio=60
重要的是要注意,只有在启用严格过度使用会计(“vm.overcommit_memory”中的模式2)时才会遵守此限制。。这可以通过以下方式设置:
sysctl -w vm.overcommit_memory=2
这是内核document,可以很好地解释这一点。
答案 3 :(得分:0)
您可以尝试使用while(true)循环编写一个小程序。运行之后,“cat / proc / {pid} / maps”你就会知道它的初始堆大小。