Подтвердить что ты не робот

Как получить доступную память С++/g++?

Я хочу выделить свои буферы в соответствии с доступной памятью. Таким образом, когда обработка и использование памяти повышаются, но все еще остаются в доступных пределах памяти. Есть ли способ получить доступную память (я не знаю, будет ли иметь значение виртуальная или физическая память?). Метод должен быть независимым от платформы, поскольку он будет использоваться в Windows, OS X, Linux и AIX. (И если это возможно, я также хотел бы выделить часть доступной памяти для моего приложения, кто-то не изменится во время выполнения).

Изменить: я сделал это с настраиваемым распределением памяти. Я понимаю, что это не очень хорошая идея, так как большинство ОС управляют памятью для нас, но мое приложение было платформой ETL (предназначено для использования на сервере, но также использовалось на рабочем столе в качестве плагина для Adobe indesign). Итак, я запускался для выпуска, потому что вместо использования swap окна возвращали бы плохой дистрибутив, и другие приложения начинают терпеть неудачу. И поскольку меня учили избегать аварий и так, я просто пытался грациозно разлагаться.

4b9b3361

Ответ 1

Прочитав эти ответы, я удивлен, что многие считают, что компьютерная память OP принадлежит другим. Это его компьютер и его память, как он считает нужным, даже если он ломает другие системы, претендующие на это. Это интересный вопрос. В более примитивной системе я имел memavail(), который сказал бы мне об этом. Почему бы OP не взять столько памяти, сколько он хочет, не нарушая работу других систем?

Здесь есть решение, которое выделяет менее половины доступной памяти, просто чтобы быть добрым. Выход был:

Требуется 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;
}

Ответ 2

В 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, и все будет хорошо.

Ответ 3

Есть причины сделать это в HPC для научного программного обеспечения. (Не игра, веб-сайт, бизнес или встроенное программное обеспечение). Научное программное обеспечение обычно проходит через терабайты данных, чтобы пройти через одно вычисление (или запустить) (и работать в течение нескольких часов или недель) - все это невозможно сохранить в памяти (и если в один прекрасный день вы скажете, что терабайт является стандартным для любого ПК или планшета или телефона, это будет случай, когда научное программное обеспечение будет работать с петабайтами или более). Объем памяти также может определять тип метода/алгоритма, который имеет смысл. Пользователь не всегда хочет решить память и метод - у него есть другие вещи, о которых можно беспокоиться. Поэтому программист должен иметь хорошее представление о том, что доступно (4Gb или 8Gb или 64Gb или около того в эти дни), чтобы решить, будет ли метод работать автоматически, или выбрать более трудоемкий метод. Диск используется, но предпочтительнее память. И пользователям такого программного обеспечения не рекомендуется делать слишком много вещей на своем компьютере при запуске такого программного обеспечения - на самом деле они часто используют выделенные машины/серверы.

Ответ 4

Не существует независимого от платформы способа сделать это, разные операционные системы используют разные стратегии управления памятью.

Эти другие вопросы помогут:

Вы должны помнить об этом: как известно, трудно получить "реальное" значение для доступной памяти в Linux. То, что операционная система отображает как используемое процессом, не гарантирует того, что фактически выделяется для процесса.

Это обычная проблема при разработке встроенных систем Linux, таких как маршрутизаторы, где вы хотите буферировать столько, сколько позволяет оборудование. Вот ссылка на пример, показывающий, как получить эту информацию в Linux (в C):

Ответ 5

Пример Mac OS X с использованием sysctl (man 3 sysctl):

#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-подобных операционных системах?)

Ответ 6

"Официальной" функцией для этого является было std::get_temporary_buffer(). Однако вы можете проверить, имеет ли ваша платформа достойную реализацию. Я понимаю, что не все платформы ведут себя так, как хотелось бы.

Ответ 7

В приведенном ниже коде представлена ​​полная и свободная память в мегабайтах. Работает для 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;
}

Ниже представлен вывод программы по сравнению с 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

Ответ 8

Вместо того, чтобы пытаться угадать, рассмотрели ли вы возможность позволить пользователю настроить, сколько памяти использовать для буферов, а также принять несколько консервативных значений по умолчанию? Таким образом, вы все равно можете запустить (возможно, немного медленнее) без переопределения, но если пользователь знает, что для приложения доступно X-память, они могут повысить производительность, настроив эту сумму.

Ответ 9

Linux в настоящее время свободной памяти: sysconf(_SC_AVPHYS_PAGES) и get_avphys_pages()

Общий объем ОЗУ был покрыт на fooobar.com/info/109346/... sysconf(_SC_PHYS_PAGES);.

И sysconf(_SC_AVPHYS_PAGES), и get_avphys_pages() являются расширениями glibc для POSIX, которые вместо этого дают общее количество доступных в настоящее время страниц ОЗУ.

Затем вам просто нужно умножить их на sysconf(_SC_PAGE_SIZE), чтобы получить текущую свободную оперативную память.

Пример минимального запуска по адресу: C - Проверить доступную свободную оперативную память?