如何获得可用内存C ++ / g ++?

我想根据可用的内存分配我的缓冲区。 这样,当我做处理和内存使用量上升,但仍然在可用内存的限制。 有没有办法获得可用的内存(我不知道虚拟或物理内存状态会有什么区别?)。 方法必须是平台无关的,因为它将在Windows,OS X,Linux和AIX上使用。 (如果可能的话,我也想为我的应用程序分配一些可用的内存,在执行期间它不会改变的人)。

编辑:我做了可configuration的内存分配。 我知道这不是一个好主意,因为大多数操作系统都为我们pipe理内存,但是我的应用程序是一个ETL框架(打算在服务器上使用,但也被用在桌面上作为Adobe indesign的插件)。 所以,我遇到了问题,因为不使用交换,Windows将返回错误的分配和其他应用程序开始失败。 正如我被教导要避免碰撞,所以,只是试图优雅地退化。

读过这些答案,我感到惊讶的是,许多人认为OP的计算机内存属于其他人。 这是他的电脑和他认为合适的记忆,即使它打破了其他系统的声称。 这是一个有趣的问题。 在一个比较原始的系统上,我有一个memavail()来告诉我这个。 为什么操作系统不应该像他所希望的那样记忆多less内存呢?

这是一个解决scheme,分配不到一半的可用内存,只是为了善待。 输出是:

必填FFFFFFFF

要求7FFFFFFF

要求3FFFFFFF

内存大小分配= 1FFFFFFF

 #include <stdio.h> #include <stdlib.h> #define MINREQ 0xFFF // arbitrary minimum int main(void) { unsigned int required = (unsigned int)-1; // adapt to native uint char *mem = NULL; while (mem == NULL) { printf ("Required %X\n", required); mem = malloc (required); if ((required >>= 1) < MINREQ) { if (mem) free (mem); printf ("Cannot allocate enough memory\n"); return (1); } } free (mem); mem = malloc (required); if (mem == NULL) { printf ("Cannot enough allocate memory\n"); return (1); } printf ("Memory size allocated = %X\n", required); free (mem); return 0; } 

在类UNIX操作系统上,有sysconf 。

 #include <unistd.h> unsigned long long getTotalSystemMemory() { long pages = sysconf(_SC_PHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); return pages * page_size; } 

在Windows上,有GlobalMemoryStatusEx

 #include <windows.h> unsigned long long getTotalSystemMemory() { MEMORYSTATUSEX status; status.dwLength = sizeof(status); GlobalMemoryStatusEx(&status); return status.ullTotalPhys; } 

所以只要做一些幻想#ifdef ,你会很好去。

这样我就不会被压下来……正如其他人所说的,你不应该占用所有可用的空间,并且可能有更好的方法去做你真正想做的事情。 这个技术实际上并没有给你相同的内存量定义,因为一些操作系统将使用“页面”来表示他们想要的任何东西(磁盘缓冲区,I / O设备)。 你有权访问的内存空间和RAM中的物理字节之间存在巨大的断开(查看翻译后备缓冲区仅举一个例子)。

在HPC中为科学软件做这个事情是有原因的。 (不是游戏,networking,商业或embedded式软件)。 科学软件通常会通过数TB的数据来通过一个计算(或运行)(并运行几个小时或几周) – 所有这些都不能存储在内存中(如果有一天,你告诉我一个TB是任何PC的标准或平板电脑或手机,这将是科学软件预计处理PB级以上的情况)。 内存的数量也可以决定那种有意义的方法/algorithm。 用户并不总是想要决定内存和方法 – 他/她有其他的事情要担心。 所以程序员应该对可用的方法(4Gb或者8Gb或者64Gb或者这些天左右)有一个好的概念来决定一个方法是否会自动工作,或者select一个更费力的方法。 磁盘使用,但内存是可取的。 当运行这样的软件时,不鼓励这些软件的用户在他们的计算机上做太多事情 – 事实上,他们经常使用专用的机器/服务器。

没有平台独立的方式来做到这一点,不同的操作系统使用不同的内存pipe理策略。

这些其他堆栈溢出问题将有助于:

  • 如何在运行时获得内存使用情况在C + +?
  • Linux / Windows中的C / C ++内存使用API

你应该小心:在linux中获得可用内存的“真实”价值是非常困难的。 操作系统显示的进程使用的内容不能保证实际分配给进程的内容。

在开发诸如路由器之类的embedded式Linux系统时,这是一个常见的问题。 这里是一个链接到一个例子显示如何获得这个信息在Linux(在C):

使用sysctl( man 3 sysctl )的Mac OS X示例:

 #include <stdio.h> #include <stdint.h> #include <sys/types.h> #include <sys/sysctl.h> int main(void) { int mib[2] = { CTL_HW, HW_MEMSIZE }; u_int namelen = sizeof(mib) / sizeof(mib[0]); uint64_t size; size_t len = sizeof(size); if (sysctl(mib, namelen, &size, &len, NULL, 0) < 0) { perror("sysctl"); } else { printf("HW.HW_MEMSIZE = %llu bytes\n", size); } return 0; } 

(也可以在其他类似BSD的操作系统上工作)

下面的代码给出了以兆字节为单位的总内存和可用内存。 适用于FreeBSD,但是您应该能够在您的平台上使用相同/相似的sysctl可调参数,并执行相同的操作(Linux和OS X至less具有sysctl)

 #include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/sysctl.h> #include <sys/vmmeter.h> int main(){ int rc; u_int page_size; struct vmtotal vmt; size_t vmt_size, uint_size; vmt_size = sizeof(vmt); uint_size = sizeof(page_size); rc = sysctlbyname("vm.vmtotal", &vmt, &vmt_size, NULL, 0); if (rc < 0){ perror("sysctlbyname"); return 1; } rc = sysctlbyname("vm.stats.vm.v_page_size", &page_size, &uint_size, NULL, 0); if (rc < 0){ perror("sysctlbyname"); return 1; } printf("Free memory : %ld\n", vmt.t_free * (u_int64_t)page_size); printf("Available memory : %ld\n", vmt.t_avm * (u_int64_t)page_size); return 0; } 

下面是程序的输出,与我系统上的vmstat(8)输出相比较。

 ~/code/memstats % cc memstats.c ~/code/memstats % ./a.out Free memory : 5481914368 Available memory : 8473378816 ~/code/memstats % vmstat procs memory page disks faults cpu rbw avm fre flt re pi po fr sr ad0 ad1 in sy cs us sy id 0 0 0 8093M 5228M 287 0 1 0 304 133 0 0 112 9597 1652 2 1 97 

这个“官方”函数是std::get_temporary_buffer() 。 但是,您可能想要testing您的平台是否具有体面的实现。 我明白并不是所有平台的行为都符合要求。

您是否考虑让用户configuration多less内存用于缓冲区,以及假设有些保守的默认值,而不是尝试猜测? 这样,你仍然可以运行(可能稍微慢一些)而不需要覆盖,但是如果用户知道应用程序有X个可用内存,他们可以通过configuration这个数量来提高性能。