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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2513505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:45:16  来源:igfitidea点击:

How to get available memory C++/g++?

c++memory-managementcross-platform

提问by theCakeCoder

I want to allocate my buffers according to memory available. Such that, when I do processing and memory usage goes up, but still remains in available memory limits. Is there a way to get available memory (I don't know will virtual or physical memory status will make any difference ?). Method has to be platform Independent as its going to be used on Windows, OS X, Linux and AIX. (And if possible then I would also like to allocate some of available memory for my application, someone it doesn't change during the execution).

我想根据可用内存分配我的缓冲区。这样,当我进行处理时,内存使用量会增加,但仍处于可用内存限制内。有没有办法获得可用内存(我不知道虚拟或物理内存状态会有所不同吗?)。方法必须是平台独立的,因为它将在 Windows、OS X、Linux 和 AIX 上使用。(如果可能的话,我还想为我的应用程序分配一些可用内存,它在执行过程中不会改变)。

Edit: I did it with configurable memory allocation. I understand it is not good idea, as most OS manage memory for us, but my application was an ETL framework (intended to be used on server, but was also being used on desktop as a plugin for Adobe indesign). So, I was running in to issue of because instead of using swap, windows would return bad alloc and other applications start to fail. And as I was taught to avoid crashes and so, was just trying to degrade gracefully.

编辑:我用可配置的内存分配做到了。我知道这不是一个好主意,因为大多数操作系统为我们管理内存,但我的应用程序是一个 ETL 框架(打算在服务器上使用,但也在桌面上用作 Adob​​e indesign 的插件)。所以,我遇到了问题,因为不是使用交换,windows 会返回错误的分配,其他应用程序开始失败。正如我被教导要避免崩溃等,我只是试图优雅地降级。

采纳答案by Weather Vane

Having read through these answers I'm astonished that so many take the stance that OP's computer memory belongs to others. It's hiscomputer and hismemory to do with as he sees fit, even if it breaks other systems taking a claim it. It's an interesting question. On a more primitive system I had memavail()which would tell me this. Why shouldn't the OP take as much memory as he wants without upsetting other systems?

通读这些答案后,我很惊讶有这么多人认为 OP 的计算机内存属于其他人。这是他的电脑和他的记忆,他认为合适,即使它破坏了其他声称拥有它的系统。这是一个有趣的问题。在我拥有的一个更原始的系统上memavail(),它会告诉我这一点。为什么 OP 不应该在不干扰其他系统的情况下占用尽可能多的内存?

Here's a solution that allocates less than half the memory available, just to be kind. Output was:

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

Required FFFFFFFF

必需的 FFFFFFFF

Required 7FFFFFFF

需要 7FFFFFFF

Required 3FFFFFFF

需要 3FFFFFFF

Memory size allocated = 1FFFFFFF

分配的内存大小 = 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;
}

回答by Travis Gockel

On UNIX-like operating systems, there is sysconf.

在类 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;
}

On Windows, there is GlobalMemoryStatusEx:

在 Windows 上,有GlobalMemoryStatusEx

#include <windows.h>

unsigned long long getTotalSystemMemory()
{
    MEMORYSTATUSEX status;
    status.dwLength = sizeof(status);
    GlobalMemoryStatusEx(&status);
    return status.ullTotalPhys;
}

So just do some fancy #ifdefs and you'll be good to go.

所以只要做一些花哨#ifdef的事情,你就可以开始了。

回答by Paresh M

There are reasons to do want to do this in HPC for scientific software. (Not game, web, business or embedded software). Scientific software routinely go through terabytes of data to get through one computation (or run) (and run for hours or weeks) -- all of which cannot be stored in memory (and if one day you tell me a terabyte is standard for any PC or tablet or phone it will be the case that the scientific software will be expected to handle petabytes or more). The amount of memory can also dictate the kind of method/algorithm that makes sense. The user does not always want to decide the memory and method - he/she has other things to worry about. So the programmer should have a good idea of what is available (4Gb or 8Gb or 64Gb or thereabouts these days) to decide whether a method will automatically work or a more laborious method is to be chosen. Disk is used but memory is preferable. And users of such software are not encouraged to be doing too many things on their computer when running such software -- in fact, they often use dedicated machines/servers.

有理由希望在 HPC 中为科学软件执行此操作。(不是游戏、网络、商业或嵌入式软件)。科学软件通常会处理 TB 级数据以完成一次计算(或运行)(并运行数小时或数周)——所有这些都无法存储在内存中(如果有一天你告诉我 TB 是任何 PC 的标准配置)或平板电脑或手机,科学软件预计将处理 PB 或更多)。内存量也可以决定有意义的方法/算法的种类。用户并不总是想决定内存和方法——他/她还有其他事情要担心。因此,程序员应该很好地了解可用的(4Gb 或 8Gb 或 64Gb 或大约这些天)来决定一种方法是自动工作还是选择更费力的方法。使用磁盘,但最好使用内存。并且不鼓励此类软件的用户在运行此类软件时在他们的计算机上做太多事情——事实上,他们经常使用专用的机器/服务器。

回答by mikelong

There is no platform independent way to do this, different operating systems use different memory management strategies.

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

These other stack overflow questions will help:

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

You should watch out though: It is notoriously difficult to get a "real" value for available memory in linux. What the operating system displays as used by a process is no guarantee of what is actually allocated for the process.

不过,您应该注意:众所周知,在 linux 中获得可用内存的“真实”值是非常困难的。操作系统显示的进程使用的内容并不能保证实际分配给进程的内容。

This is a common issue when developing embedded linux systems such as routers, where you want to buffer as much as the hardware allows. Here is a link to an example showing how to get this information in a linux (in C):

这是开发嵌入式 linux 系统(例如路由器)时的常见问题,您希望在硬件允许的范围内进行缓冲。这是一个示例的链接,该示例展示了如何在 linux 中(在 C 中)获取此信息:

回答by Paul R

Mac OS X example using sysctl (man 3 sysctl):

使用 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;
}

(may also work on other BSD-like operating systems ?)

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

回答by fnisi

The code below gives the total and free memory in Megabytes. Works for FreeBSD, but you should be able to use same/similar sysctl tunables on your platform and do to the same thing (Linux & OS X have sysctl at least)

下面的代码给出了以兆字节为单位的总内存和可用内存。适用于 FreeBSD,但您应该能够在您的平台上使用相同/相似的 sysctl 可调参数并做同样的事情(Linux 和 OS X 至少有 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;
}

Below is the output of the program, compared with the vmstat(8)output on my system.

下面是程序的输出,与我系统上的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
 r b w     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

回答by MSalters

The "official" function for this iswas std::get_temporary_buffer(). However, you might want to test whether your platform has a decent implemenation. I understand that not all platforms behave as desired.

对此的“官方”功能was std::get_temporary_buffer()。但是,您可能想测试您的平台是否具有良好的实现。我了解并非所有平台都按预期运行。

回答by Mark B

Instead of trying to guess, have you considered letting the user configure how much memory to use for buffers, as well as assuming somewhat conservative defaults? This way you can still run (possibly slightly slower) with no override, but if the user know there is X memory available for the app they can improve performance by configuring that amount.

与其试图猜测,您是否考虑过让用户配置缓冲区使用多少内存,并假设一些保守的默认值?这样你仍然可以在没有覆盖的情况下运行(可能稍微慢一些),但是如果用户知道应用程序有 X 内存可用,他们可以通过配置该数量来提高性能。