LINUX.ORG.RU

Как получить размер максимального объема памяти, которую может занять процесс?


0

1

Собственно сабж. На оффтопике это делается таким образом:

 MEMORYSTATUSEX memStatus;
 memStatus.dwLength = sizeof(memStatus);
 GlobalMemoryStatusEx(&memStatus);
 maxVirtualMemorySizeForProcess = memStatus.ullTotalVirtual;

Уважаемые знатоки, внимание вопрос:

Как то же самое получить на онтопике?

посмотри в сырцы ядра планировщика памяти. Обычно slab

darkenshvein ★★★★★
()

А смысл? Ядро может удовлетворить заявку на выделение памяти в количестве, превышающем физически доступный объём RAM+swap, но позже убить процесс, когда реальное использование выделенных странц подберётся к некоторому пределу.

Krieger_Od ★★
()
Ответ на: комментарий от nanoolinux

а что из вывода максимальный размер виртуальной памяти процесса? VmallocTotal?

EugeneBas ★★
() автор топика
Ответ на: комментарий от Krieger_Od

на данный момент у меня задача не давать своему приложению выделить памяти больше, чем максимальный размер виртуального адресного пространства (очень актуально для 32-битных осей)

EugeneBas ★★
() автор топика
Ответ на: комментарий от EugeneBas

Неправильно ставится задача. Не к размеру адресного пространства тебе нужно привязываться. Если ты опасаешься OOM-killer-а, то надо внимательно смотреть, как он работает, и мне кажется, от воли одного твоего приложения мало что зависит. Проще ввести какой-то настраиваемый пользователем предел занимаемой полезной памяти.

Krieger_Od ★★
()
Ответ на: комментарий от EugeneBas

не давать своему приложению выделить памяти больше, чем

неправильно решаешь. правильно так:

try{
   ..... new .... [...];
} catch (std::bad_alloc &e) {
   printf("buy some memory, bro");
}

nanoolinux ★★★★
()
Последнее исправление: nanoolinux (всего исправлений: 1)
Ответ на: комментарий от EugeneBas

не давать своему приложению выделить памяти больше, чем максимальный размер виртуального адресного пространства (очень актуально для 32-битных осей)

Дык 2 гига и всё. В чем тогда вопрос?

no-such-file ★★★★★
()
Ответ на: комментарий от Krieger_Od

так у меня примерно так и есть, только я хочу чтобы не пользователь указывал предел занимаемой памяти, а чтобы она считалась считалась процентом от максимума размера виртуальной памяти (сумма свободного свопа и физической памяти пока не учитываю, но собираюсь)

EugeneBas ★★
() автор топика
Ответ на: комментарий от arturpub

похоже на правду (с работы ушел - не могу проверить)

EugeneBas ★★
() автор топика
Ответ на: комментарий от nanoolinux

на сколько я знаю, есть винды, у которых работает в юзерспейсе, подозреваю, что есть и линуха такие

EugeneBas ★★
() автор топика
Ответ на: комментарий от EugeneBas

про PAE слышал?

Как это влияет на количество адресов доступных процессу? Правильно, никак.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Да ну,

у меня такое в продакшн коде. работает на ура.

nanoolinux ★★★★
()
Ответ на: комментарий от EugeneBas

Это не имеет смысла, ибо твой кусок говна убьют до того, как ты упрёшься в «размер вирт. адресного пространства».

Слежка за памятью/адресами не имеет смысла. Для того, чтобы ты не особо фейлился с памятью в линуксе есть оверкоммит, который вернёт тебе ошибку, если ты запросишь виртпамяти больше, чем есть реальной. Следи за ошибками. Это нужно только для 32-битного говна, которое протухло лет 8назад и уже не актуально для всего, чему нужно работать с памятью.

Сейчас же следить за варадресами нахрен не упала, а за реальной памятью ты следить не особо можешь и тебя не должно это волновать. Если ты хочешь надёжную память, которая не отвалится - юзай MAP_POPULATE.

Если ты хреначишь на уровне либц - тебе нет смысла даже об этом думать. Та маздайская параша нидаёт ничего, твоё говно так же упадёт.

anonymous
()
Ответ на: комментарий от EugeneBas

про PAE слышал?

а при чем тут PAE? юзерспейс про него все равно ничего не знает и он работает в тех же 32х битах. в винде эти 4 гига делятся на 2 ядро, 2 юзер; в линухе 1 к 3, соответственно. Про ООМ убийцу и рлимиты уже написали. Дальше тебе решать, каким образом жить твоей софтине.

Deleted
()
Ответ на: комментарий от Deleted

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

PS: если у тебя вообще такая нужда возникла, стоит всерьез подумать над:

1) может что-то не так делаю

2) перейти на 64 бита

Deleted
()
Ответ на: комментарий от Deleted

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

именно, соль в том, чтобы узнать какое распределение на текущей системе.

перейти на 64 бита

софт есть и в 64-битном варианте, но он древний и приходится поддерживать пользователей, которые еще сидят на 32 битах

может что-то не так делаю

возможно, но данный момент решение узнать заранее лимит и при приближении к нему попросить пользователя выполнить действия, которые позволят освободить необходимую память для дальнейшей работы, выглядит разумным

EugeneBas ★★
() автор топика

не будь мудаком. Вот посмотри как другие делают:

Memory usage The memory usage of xz varies from a few hundred kilobytes to several gigabytes depending on the compression settings. The settings used when compressing a file determine the memory requirements of the decompressor. Typically the decompressor needs 5 % to 20 % of the amount of memory that the compressor needed when creating the file. For example, decom- pressing a file created with xz -9 currently requires 65 MiB of memory. Still, it is possi- ble to have .xz files that require several gigabytes of memory to decompress.

Especially users of older systems may find the possibility of very large memory usage annoy- ing. To prevent uncomfortable surprises, xz has a built-in memory usage limiter, which is disabled by default. While some operating systems provide ways to limit the memory usage of processes, relying on it wasn't deemed to be flexible enough (e.g. using ulimit(1) to limit virtual memory tends to cripple mmap(2)).

The memory usage limiter can be enabled with the command line option --memlimit=limit. Often it is more convenient to enable the limiter by default by setting the environment variable XZ_DEFAULTS, e.g. XZ_DEFAULTS=--memlimit=150MiB. It is possible to set the limits separately for compression and decompression by using --memlimit-compress=limit and --mem- limit-decompress=limit. Using these two options outside XZ_DEFAULTS is rarely useful because a single run of xz cannot do both compression and decompression and --memlimit=limit (or -M limit) is shorter to type on the command line.

If the specified memory usage limit is exceeded when decompressing, xz will display an error and decompressing the file will fail. If the limit is exceeded when compressing, xz will try to scale the settings down so that the limit is no longer exceeded (except when using --format=raw or --no-adjust). This way the operation won't fail unless the limit is very small. The scaling of the settings is done in steps that don't match the compression level presets, e.g. if the limit is only slightly less than the amount required for xz -9, the settings will be scaled down only a little, not all the way down to xz -8.

вот тебе типичная программа, которая может (теоретически) жрать сколько угодно(ей) памяти.

emulek
()
Ответ на: комментарий от EugeneBas

именно, соль в том, чтобы узнать какое распределение на текущей системе.

//FIXME такой говнокод работает, но за него бьют канделябрами по башке 
#if sizeof(*int) == 8
// говнокод для 64х битных систем
#else
// говнокод для остальных, т.е. для 32х битных
#endif
emulek
()
Ответ на: комментарий от emulek

Обсосок, каким образом твоя гнилая портянка относится к теме? И что тут конкретно другие делают. Это говно отвалится точно так же. Любой кусок говна может делать тоже самое, но как жешь это относится к теме? Улимит протух лет 500назад.

anonymous
()
Ответ на: комментарий от emulek

Помнится, для определения тупо-остро-среднеконечности тоже нехилый такой макрос выдумали. А то и функцию. Берем объединение массива char и uint64_t, пишем в массив что-нибудь вроде 1..8, а потом анализируем, что в длинное попало (или наоборот). Ну вот неужто нельзя какой-нибудь эдакий флаг было придумать, чтобы не извращаться с этими велосипедами? Я так с этой сраной "конечностью" полтора дня себе мозг выносил с настройками SPI, пока не удосужился порядок байтиков проверить...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

А какой флаг? Кроме LE/BE есть еще куча теоретических вариантов, по количеству перестановок 1..8. Хошь без костылей — юзай htonl/ntohl, они гарантированно network byte order выдают. А вообще детская ошибка же, ну ;)

arturpub ★★
()
Ответ на: комментарий от Eddy_Em

Всё это есть - просто тебя учил маздайский сброд, а возможно ты им и был:

int main(void) {
  fprintf(stdout, "%u, %u\n", __WORDSIZE, __BYTE_ORDER);
  if(__x86_64__) fprintf(stdout, "ITS64b\n");
}
int is_little(void) {
  return (1ul & 1);
}

Это не работает? Чём я как-то слабо представляю себе битопы на неинтелах.

anonymous
()
Ответ на: комментарий от no-such-file
λ> cat test.cpp
#include <iostream>
#include <string>

using namespace std;

int main()
{
  try
    {
      while (1)
        {
          new char[10000];
        }
    }
  catch (std::bad_alloc &e)
    {
      cout << "buy some memory, bro\n";
    }

  return 0;
}
λ> g++ test.cpp
λ> ./a.out 
buy some memory, bro
Deleted
()
Ответ на: комментарий от arturpub

Откуда sizeof в препроцессоре?

это константа известная во время компиляции.

Что есть *int?

указатель

почему не *long?

не возражаю (:

PS: слово «говнокод» плохо видно?

emulek
()
Ответ на: комментарий от Eddy_Em

Ну вот неужто нельзя какой-нибудь эдакий флаг было придумать, чтобы не извращаться с этими велосипедами?

нет. Говнокодеры должны страдать.

emulek
()
Ответ на: комментарий от Deleted

man overcommit, bro. Это никак не показывает реальную память и никак не относится к реальной памяти.

$ ./a.out 
Убито
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <stdint.h>

#define bind(f, arg) ({typeof(f(arg)) new(void) { return f(arg);} new;})

void * alloc_page(uint64_t flags) {
  return mmap(NULL, 4096, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | flags, 0, 0);
}

#define PINMB ((1024ul*1024)/4096)
#define MYMEM ((1024ul*1024*1024)*16)

typedef void*(*allocf_t)(void);

int overmax(void) {return !fprintf(stderr, "OVERMAX\n");}

uint64_t find_max(allocf_t f) {
  uint64_t i = 0, max = MYMEM/4096;
  while(({int t = (f() != -1ul); i += t; t;}) && ((i < max) || overmax()));
  return i;
}

int main(void) {
  fprintf(stderr, "%luMB\n", find_max(bind(alloc_page, 0))/PINMB);
  fprintf(stderr, "%luMB\n", find_max(bind(alloc_page, MAP_POPULATE))/PINMB);
  fprintf(stderr, "%luMB\n", find_max(bind(alloc_page, MAP_POPULATE))/PINMB);
  fprintf(stderr, "%luMB\n", find_max(bind(malloc, 4096))/PINMB);
}

На тебе тестик. А знаешь почему так происходит? Маллок - параша. Все ваши мифы и легенды со днища океана, проверка памяти и прочее - не работает в реальном мире, да и не нужны. Маллок юзает память, которую «выделяет» - твой бэдаллок сработает только на фарте.

$ ./build/for_alv 
OVERMAX//"несвязанной" "памяти" может быть сколько угодно, она не ограниченна твоей физической - это просто виртадреса.
16384MB//обламалось на 16гигах, ибо у меня столько памяти - я там поставил ограничение.
13429MB//тут оно сжирает всю доступную физическую память.
0MB//тут вызывается снова, но памяти уже нет.
Убито//а тут вызывается маллок и благополучно ООМ-киллер киляет "процесс".
anonymous
()
Ответ на: комментарий от kdev

Насколько я понял в формально в посиксе его нет, но реально во ?всех посиксах есть. sys-libs/glibc-2.17 (/usr/include/endian.h)

anonymous
()
Ответ на: комментарий от anonymous

man overcommit, bro. Это никак не показывает реальную память и никак не относится к реальной памяти.

Я ничего не говорил о памяти. Я говорил про exception, и ничего более.

Deleted
()
Ответ на: комментарий от emulek

Говнокодеры должны страдать.

А ты не говнокодер? И как же ты определяешь архитектуру, на которой компиляется код?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от arturpub

Хошь без костылей — юзай htonl/ntohl, они гарантированно network byte order выдают.

Я про этот быдлокод костыльный и говорил!

А вообще детская ошибка же, ну ;)

Согласен: надо даташит читать внимательно и сразу откладывать в память, какая у тебя целевая архитектура и что там за "конечность".

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Deleted

Который не работает. ты бэдаллок зачем-то привел, только вот он не работает - зачем ты про него говорил? Форфан? И да - ты ответил на онтопик, а онтопик - память, ты говорил о памяти априори.

anonymous
()
Ответ на: комментарий от Eddy_Em

А если ты не будешь слепым? __WORDSIZE - тебе в помощь. Ты просто так кукарекаешь, какую цель ты преследовал запостив свой недокоммент?

Это пример детекта х86_64 - ты можешь так же детектить арм, мип, спарк и хренарк.

anonymous
()
Ответ на: комментарий от Eddy_Em

Он обоссанный ноль. Это где-то на уровне 1курса недовуза, максимум 2-го - он ничего не определяет, да и маны не читает, да и просто идиот. Так же как и ты выше - балаболил форфан, лижбы балаболить.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.