如何在C++/g++中获取可用内存?
如何在C++/g++中获取可用内存?
我想根据可用内存来分配我的缓冲区。这样,当我进行处理时,内存使用量会增加,但仍保持在可用内存限制范围内。是否有一种方法可以获取可用内存(我不知道虚拟内存或物理内存状态是否会有任何差异?)?该方法必须是平台无关的,因为它将在Windows、OS X、Linux和AIX上使用。(如果可能的话,我还想分配一些可用内存给我的应用程序,以确保在执行过程中不会发生变化)。\n编辑:我使用可配置的内存分配实现了它。\n我明白这不是一个好主意,因为大多数操作系统已经为我们管理了内存,但我的应用程序是一个ETL框架(用于服务器,但也作为Adobe InDesign插件在桌面上使用)。所以,我遇到的问题是,Windows不是使用交换空间,而是返回“bad alloc”,导致其他应用程序开始失败。因为我被教导要避免崩溃,所以我只是试图优雅地降级处理。
如何在C++/g++中获取可用内存?
在不同的操作系统中,使用不同的内存管理策略,因此没有一个平台无关的方法来获取可用内存。但是,以下的stackoverflow问题可以帮助解决这个问题:
- [如何在C++中在运行时获取内存使用情况?](https://stackoverflow.com/questions/669438)
- [Linux/Windows中的C/C++内存使用API](https://stackoverflow.com/questions/1674652)
然而,需要注意的是,在Linux中获取"真实"的可用内存值非常困难。操作系统显示的进程使用的内存并不保证实际为进程分配的内存。这在开发嵌入式Linux系统(例如路由器)时是一个常见问题,因为您希望尽可能多地利用硬件缓冲区。下面是一个示例链接,展示了如何在Linux中获取这些信息(使用C语言):
- [在Linux中确定可用内存](http://www.unix.com/programming/25035-determining-free-available-memory-mv-linux.html)
Linux使用惰性分配,可以通过在内存中写入数据来保证内存已分配。
如何获取可用的内存 C++/g++?
在科学软件的高性能计算(HPC)中,有一些原因需要这样做(而不是游戏、网络、商业或嵌入式软件)。科学软件通常需要处理大量的数据来进行计算(或运行)(并且运行时间长达几小时或几周),所有这些数据都无法存储在内存中(如果有一天你告诉我一台个人电脑、平板电脑或手机上有1TB的内存是标准配置,那么科学软件将被期望处理PB级别或更多的数据)。内存的大小还可以决定哪种方法/算法是合理的。用户并不总是希望决定内存和方法 - 他/她还有其他事情要担心。因此,程序员应该对可用的内存有一个很好的了解(现在一般是4GB、8GB或64GB左右),以决定是否选择自动工作的方法还是选择更费力的方法。虽然也可以使用硬盘,但内存更可取。而在运行此类软件时,并不鼓励用户在计算机上做太多其他事情 - 实际上,他们经常使用专用的机器/服务器。
这不完全是科学软件,我正在构建一个ETL框架,当然这个框架是用于运行在专用服务器上的。可能需要设置一个最大允许内存大小,就像Java或Matlab需要启动参数一样。
至少在渲染软件中,有理由这样做。你希望尽可能使用你拥有的内存。例如:可用的物理内存(×α,其中0.5<α<0.8)将是光子映射大小的限制。再加上一些min(physi, 2GiB)
,以避免拥有256GB内存的机器花费太长时间来构建光子映射。但是你仍然可以想象在游戏中漫游,我见过一些引擎在维持内存目标时将资源流入和流出。你拥有的内存越多,你能看到的范围就越远。
如何获取C++/g++中的可用内存?
在类UNIX操作系统中,有sysconf函数可以获取可用内存,代码如下:
#includeunsigned long long getTotalSystemMemory() { long pages = sysconf(_SC_PHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); return pages * page_size; }
在Windows系统中,有GlobalMemoryStatusEx函数可以获取可用内存,代码如下:
#includeunsigned long long getTotalSystemMemory() { MEMORYSTATUSEX status; status.dwLength = sizeof(status); GlobalMemoryStatusEx(&status); return status.ullTotalPhys; }
只需要使用一些条件编译指令,就可以根据不同的操作系统选择不同的方法。
这篇文章中的代码非常有用,不会被贬低。即使我们认为这是一个不好的主意,但如果有人真的想要做一些愚蠢的事情(虽然我不愿意用这个词),我们又有什么理由拒绝给他们提供工具呢?
我并不是想要使用所有的内存,而是不想加载太多的数据,以免超过可用内存而无法处理(我希望保持在未使用或其他进程可能不会访问的空间内)。再次强调,我并不愚蠢到想要分配所有可用的内存,而是想要决定在应用程序上设置什么限制,以防止它吸取所有内存并崩溃。
对于某些操作系统,sysctl可能是sysconf的更好替代方法。参见man 3 sysctl。
在32位机器上,可以安全地假设有2GB的空间可供使用。如果用户没有这么多物理内存,操作系统会为您处理所有的虚拟内存(这是PC的好处)。但是进行一些启发式处理来确定您应该使用多少内存是很好的,但这是一个非常冒险的游戏,因为“这台计算机有多少内存?”这个问题的定义非常模糊。
我不知道还有另一种方法!
这对我来说非常有用,因为我要做的是在用户使用了大量物理内存时警告他们。我知道我可以使用更多内存并进行虚拟内存管理,但如果我使用的物理RAM超过了我想使用的量,我希望能够警告用户,因为这会导致由于产生的页面而导致的减速。
小问题:status.ullTotalPhys是一个unsigned long long类型;如果方法的返回类型是long,那么在某些系统上会得到不符合逻辑的结果。在我的系统上,运行代码会得到一个返回值为-729088的结果,但将其更改为与ullTotalPhys的类型匹配后,将得到正确的21474107392。
这是一个很好的观点...我将代码中的long更改为size_t,这应该在任何具有非分段寻址的系统上都可以使用。
当然是有用的。谁没有打开系统页面(Win + Pause快捷键在MS操作系统中)并喜欢“哇,我有16GB”。所以至少它提供了系统信息的目的。
这段代码似乎返回一个有效值,但我不确定它是否正常工作。我在一个具有多个MPI节点的网格上运行了几天的代码。返回值在所有天和所有MPI节点上都是相同的。
我认为这是预期的——sysconf(_SC_PHYS_PAGES)正在获取系统的内存量,这通常不会经常更改。
顺便说一下,_SC_PHYS_PAGES并不是POSIX规范的一部分。