LINUX.ORG.RU

Calloc нынче ни на что не влияет что-ли?

 ,


1

5

MWE:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char u8;
typedef unsigned int  u32;

#define GB (1024ul * 1024ul * 1024ul)
#define TEST_SIZE (10)

int zerofy = 1;

static u8 * alloc(u32 size)
{
    u8 * res = calloc(size, 1);
    
    if (!res)
    {
        printf(" * Cannot alloc %u bytes\n", size);
        return NULL;
    }
    else
    {
        printf(" * Allocated %u bytes [%p]\n", size, res);
    }

    if (zerofy)
        memset(res, 0, size);

    return res;
}

static void rapemem(u32 zero)
{
    u32 i;
    u8 * p[TEST_SIZE];

    printf("Switching zerofy to %u\n", zero);
    zerofy = zero;

    for (i = 0; i < TEST_SIZE; i++)
        p[i] = alloc(GB);

    for (i = 0; i < TEST_SIZE; i++)
        free(p[i]);
}

int main(void)
{
    system("free -mh");
    printf("\n\n");

    rapemem(0);
    rapemem(1);
    rapemem(0);

    return 0;
}

Выхлоп:

alex@alex-thinkpad-l560:~/Разработка/C/Tests/calloc$ gcc -std=c89 poc.c 
alex@alex-thinkpad-l560:~/Разработка/C/Tests/calloc$ ./a.out 
              total        used        free      shared  buff/cache   available
Память:        7,6G        2,1G        4,2G        396M        1,2G        4,8G
Подкачка:          0B          0B          0B


Switching zerofy to 0
 * Allocated 1073741824 bytes [0x7fe248a9b010]
 * Allocated 1073741824 bytes [0x7fe208a9a010]
 * Allocated 1073741824 bytes [0x7fe1c8a99010]
 * Allocated 1073741824 bytes [0x7fe188a98010]
 * Allocated 1073741824 bytes [0x7fe148a97010]
 * Allocated 1073741824 bytes [0x7fe108a96010]
 * Allocated 1073741824 bytes [0x7fe0c8a95010]
 * Allocated 1073741824 bytes [0x7fe088a94010]
 * Allocated 1073741824 bytes [0x7fe048a93010]
 * Allocated 1073741824 bytes [0x7fe008a92010]
Switching zerofy to 1
 * Allocated 1073741824 bytes [0x7fe248a9b010]
 * Allocated 1073741824 bytes [0x7fe208a9a010]
 * Allocated 1073741824 bytes [0x7fe1c8a99010]
 * Allocated 1073741824 bytes [0x7fe188a98010]
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
Switching zerofy to 0
 * Allocated 1073741824 bytes [0x7fe248a9b010]
 * Allocated 1073741824 bytes [0x7fe208a9a010]
 * Allocated 1073741824 bytes [0x7fe1c8a99010]
 * Allocated 1073741824 bytes [0x7fe188a98010]
 * Allocated 1073741824 bytes [0x7fe143fff010]
 * Allocated 1073741824 bytes [0x7fe103ffe010]
 * Allocated 1073741824 bytes [0x7fe0c3ffd010]
 * Allocated 1073741824 bytes [0x7fe083ffc010]
 * Allocated 1073741824 bytes [0x7fe043ffb010]
 * Allocated 1073741824 bytes [0x7fe003ffa010]

WTF вообще? Теперь и calloc выделению доверять нельзя? Да здравствуют SIGSEGV без вариантов проверить выделение?

Я знаю про оптимистичное выделение, но всю жизнь эта ботва была только с malloc, calloc от этой херни был свободен так как занулял память.

★★★★★

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

Ты можешь сколь угодно долго верить в том, что проверил на null и уже не говнокод, но это не так. Это падающий говнокод, который работает лишь чисто случайно. Во что бы ты там не верил - это всегда будет так. Такие дела.

Это не говнокод. Это рантайм говно. Или покажи где в стандарте C описан крэш по обращению к выделенной через malloc памяти как дозволенное поведение.

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

dzidzitop ★★
()
Последнее исправление: dzidzitop (всего исправлений: 2)
Ответ на: комментарий от PPP328

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

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

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

Люто, бешено, плюсую. Хоть один адекват среди этих «богов абстракции». Сейчас они объяснят, что стандарт С устарел на 60 лет и падать по обращению к памяти - нормально.

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

А ничего что у OOM Killer в Linux есть score_adj? Например тот же sshd ставит его таким, чтобы быть прибитым в самом последнем случае, даже если он сожрёт больше всего памяти.

Тот факт, что ты оставил его по умолчанию(настраивается через /proc) и процесс был прибит на общих основаниях - только твои проблемы.

Правда эти настройки не отменяют первопричину проблемы, о которой тут идёт речь изначально...

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

Это не говнокод. Это рантайм говно.

Выучи вначале базовые определения. Рантайм - это и есть libc.

Или покажи где в стандарте C описан крэш по обращению к выделенной через malloc памяти как дозволенное поведение.

Опять же - ты пишешь полный бред. Стандарт C никак не определяет память. От слова совсем. Он вообще не определяет ничего.

С таким подходом ты можешь уйти очень далеко. А где в стандарте вообще описан креш? А где в стандарте описал sigkill? sigstop? Ведь программа должна работать?

Ну и да, никакого крэша там не будет. Там будет вставание раком системы в oom.

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

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

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

это лебедь, рак и щука.

1) Компилятор. Ему похер на то, что у системы нет физической памяти, замапленной на виртуальную память. Он выкидывает инициализацию такой памяти, поскольку дальше нет чтения записанных значений.

2) ОС. Ей похер, что программы будут крешиться - она экономит общее потребление памяти и немножко улучшает производительность.

3) C. Не имеет средств управления ни первым ни вторым, кроме жалкого volatile или использования платформоспецифичных API.

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

Расскажешь, что такое compile time тогда?

Вставание раком - это разрешённое поведение. Претензий никаких. Кроме того, что надёжность таких систем не ахти.

Ну и повторюсь - компилятор выкидывает инициализацию памяти как non-observable behaviour согласно стандарту языка C. Агитки ты из почтового ящика достаёшь.

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

1) Компилятор. Ему похер на то, что у системы нет физической памяти, замапленной на виртуальную память. Он выкидывает инициализацию такой памяти, поскольку дальше нет чтения записанных значений.

Неверно. https://godbolt.org/g/bWmEQn Он может это выпилить только, если чтения этих значений действительно нет. Т.е. он может это доказать. Если же это не так - этого быть не может.

2) ОС. Ей похер, что программы будут крешиться - она экономит общее потребление памяти и немножко улучшает производительность.

К экономии памяти это отношения не имеет. И это не «немножко» улучшает. Оно как минимум по иному работать попросту не может.

3) C. Не имеет средств управления ни первым ни вторым, кроме жалкого volatile или использования платформоспецифичных API.

Как и никто другой. И чем же волатайл жалкий? Потому что ты так сказал?

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

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

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

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

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

Java гарантирует, что если new вернулся, то память уже выделена, готова и занулена. За счёт процессорного времени.

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

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

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

Расскажешь, что такое compile time тогда?

Причём тут компилтайм? Ты сказал, что рантайм говно, но при этом ныл про то, что система виновата. Т.е. ты либо сам себе противоречишь, либо назвал рантаймом ведро, что как минимум странно.

Кроме того, что надёжность таких систем не ахти.

Надёжность всего, что основано на вере - не ахти. И что-бы такого не было - так делать попросту не нужно. И не нужно искать оправдания.

у и повторюсь - компилятор выкидывает инициализацию памяти как non-observable behaviour согласно стандарту языка C. Агитки ты из почтового ящика достаёшь.

Ничего ты не повторяешь. Ты увидел это в агитке и ретранслируешь. И я знаю из какой именно агитки ты это взял. Зачем ты включаешь дурака?

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

А еще приложения любят мапить в память файлы, часто очень большие, которые тоже не читаются во всех местах одновременно.

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

Рантаймом я назвал (то, что происходит во) время исполнения программы.

Вероятно, я взял это из ПВС студии. Но точно не скажу. При этом компилятор *может* делать такие оптимизации. Если может показать, что отсутствие этого кода не влияет на observable behaviour. А если какой-нибудь clang этого сейчас не делает - это проблемы пользователей clang.

А какие чудесатые чудесатости делает GCC в процессе компиляции - наблюдал неоднократно. Инициализацией памяти не занимаюсь - поэтому за такую оптимизацию не скажу.

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

Верно - если сможет доказать.

А сможет он это доказать только в том случае, если его действительно нет. В этом и проблема всяких экспертов с помойки с их ахренительными тестами.

Java гарантирует, что если new вернулся, то память уже выделена, готова и занулена. За счёт процессорного времени.

Не только, jvm такая же программа, которая так же как и все авойдит oom через преаллокцию хипа. Насколько я знаю - это работает именно так, а иначе жвм так же упадёт.

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

Не знаю к чему ты это написал, но волатайл нужен там, где он нужен. И в данном случае он не нужен. И про какие затраты ты говоришь - я так же не понимаю.

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

Прошивка - это про мкашки без мму. Там у тебя никакой виртпамяти нет.

А если ты про прошивку под линукс, то тебе ничего не мешает использовать платформо-специфичное апи.

Хочется гарантий - контролируй, а не хочешь - никаких гарантий не будет. Так работает эта реальность.

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

Рантаймом я назвал (то, что происходит во) время исполнения программы.

Очень странно ведро причислять к рантайму программы.

Вероятно, я взял это из ПВС студии. Но точно не скажу.

Правильно.

При этом компилятор *может* делать такие оптимизации.

Не может.

Если может показать, что отсутствие этого кода не влияет на observable behaviour.

И тогда эта оптимизация будет валидной. Но в твоём случае это не так.

Если где-то есть использование памяти после мемсета, то он должен так быть. Это как максимум можно заменить на частичный мемсет, если используется какой-то кусок/куски вместо цельного куска из под маллока.

А если ты хочешь использовать маллок для префолта, а потом не юзать эту память - у тебя что-то явно пошло не так. И память в любом случае будет инициализирована - иначе это невалидная программа и баг в компиляторе, либо это просто не компилятор.

А если какой-нибудь clang этого сейчас не делает - это проблемы пользователей clang.

Тебе показали все компиляторы, которые этого не делают и никогда не будут делать, ибо их разработчики не дауны.

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

В данном же случае инициализация в любом случае будет и абсолютно неважно она будет в мемсете, либо после его.

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

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

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

jvm владеет своим хипом. Память, которая вернул new уже доступна вся и сразу, без фризов, oom-killer и прочей ереси. Если памяти мало, то сам new может очень (минуты, если сконфигурировать) долго тупить, перед тем, как кинуть OOMException или вернуть память после очередного цикла сборки мусора.

Инициализация результата malloc через указатель на volatile T позволит проинициализировать память с тем, чтобы она вся была доступна. Хотя как там система отреагирует на то, что есть вся страница памяти, инициализированная нулём - это уж как фантазия осописцев позволит.

Бытовой вариант - программулька для RapsberryPi, которая на пины подаёт сигналы в зависимости от состояния других пинов. Можно сказать - используй нормальный микроконтроллер, но вопрос о гарантиях, которых нет. Т.е. забываем про malloc и фигачим память через mmap с ключиками, лучше с преаллокацией под все возможные варианты. Да и сервер, или научвычислительная программка на третий день работы, которая тихо начала ждать, пока ему система выделит память - тоже не ахти.

Хочется гарантий - контролируй, а не хочешь - никаких гарантий не будет.

Типо того.

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

Рантайм - это все процессы, происходящие во время выполнения программы. libс - это runtime support library, а не рантайм. Но в общем не суть.

Компилятор может делать всё, что ему не запрещено. Такие оптимизации ему не запрещены.

Это как максимум можно заменить на частичный мемсет,

и это одно из возможных поведений.


А если ты хочешь использовать маллок для префолта, а потом не юзать эту память - у тебя что-то явно пошло не так

Псевдокод (сигнатуры не помню - не в них суть)
int *data = (int *)malloc(100500 * sizeof(int));
memset(data, 100500, 0);
for (volatile unsigned long long i = 0; i < 10000000000000000000llu; ++i);
data[100000] = (int) rand();
// use data[100000];
int x = data[100000];

Гарантий, что память будет в полном пользовании программы перед циклом - нет. Т.е. через 100 лет, когда цикл пройдёт, может быть фриз на обращении к памяти после цикла. А сам код на месте цикла может запускать какую-то производственную процедуру, и после него код должен работать как часы.
А компилятору можно выкинуть memset, т.к. этот memset не имеет побочных эффектов с точки зрения компилятора языка C.

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

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

Из этого ничего не следует.

jvm владеет своим хипом. Память, которая вернул new уже доступна вся и сразу, без фризов, oom-killer и прочей ереси. Если памяти мало, то сам new может очень (минуты, если сконфигурировать) долго тупить, перед тем, как кинуть OOMException или вернуть память после очередного цикла сборки мусора.

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

В данном случае программой является не жаба-лапша, в жвм. И все насрать что там и кому гарантирует жава, ведь система жвм ничего не гарантирует. Такие дела.

Бытовой вариант - программулька для RapsberryPi, которая на пины подаёт сигналы в зависимости от состояния других пинов. Можно сказать - используй нормальный микроконтроллер, но вопрос о гарантиях, которых нет. Т.е. забываем про malloc и фигачим память через mmap с ключиками, лучше с преаллокацией под все возможные варианты. Да и сервер, или научвычислительная программка на третий день работы, которая тихо начала ждать, пока ему система выделит память - тоже не ахти.

Да, забываем про маллок. Иного пути нет, если ты хочешь каких-то гарантий.

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

Компилятор может делать всё, что ему не запрещено. Такие оптимизации ему не запрещены.

Запрещены.

и это одно из возможных поведений.

Единственное.

Псевдокод (сигнатуры не помню - не в них суть)

Всевдокод не имеет смысла. Это типичнай проблема, когда ты даже не можешь придумать осмысленный пример. В твоём коде аллокация вообще не имеет смысла и не нужна.

А вот если бы ты её засунул в свой цикл, то никакой бы компилятор её никогда бы не выкинул.

Гарантий, что память будет в полном пользовании программы перед циклом - нет.

Правильно, потому что это не имеет смысла.

А сам код на месте цикла может запускать какую-то производственную процедуру

Если он её запускает не используя data[] - твой пример не имеет смысла, а если использует - компилятор обязан посмотреть в твою процедуру.

А компилятору можно выкинуть memset, т.к. этот memset не имеет побочных эффектов с точки зрения компилятора языка C.

Он не имеет побочных эффектов и с точки зрения логики реального мира. Это попросту не имеет смысла. Выделять память, чтобы потом её не использовать.

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

в 7.14 и 7.26.6 ваш КО C99/C11

КО провалился. Во-первых подобных сигналов там нет, а вторых это никакого отношения к тому, о чём я писал - не имеет. Я писал именно об определении логики работы сигналов( т.е. воздействии на исполнение программы), которая нигде в стандарте не определена. Ну и естественно signal.h - это совершенно не то.

Если попроще. Это находится в разделе library, который никакого отношения к самому языку и среде исполнения не имеет.

В рамках стандарта «определена» только обработка сигналов, а всё остальное - нет. Всё остальное, что система может делать с программой - нигде не описано. Она может делать всё что угодно.

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

Запрещены.

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

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

1) Компилятор. Ему похер на то, что у системы нет физической памяти, замапленной на виртуальную память. Он выкидывает инициализацию такой памяти, поскольку дальше нет чтения записанных значений.

Компилятор. Выкидывает запись памяти. По адресу, полученному из библиотечной функции с сайд-эффектами.

А если я сделаю:

void * addr = получить_адрес_замапленной_видеопамяти().
memcpy(addr, next_frame, frame_size);
, то компилятор этот код тоже выкинет?

Ой кончай заливать!

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

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

Сложно читать маны, понимаю. Но ты попробоуй. Вдруг понравится?

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

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

void * мой_васянистый_маллок(size_t size) {
    void * p = malloc(size);
    memset(p, 0, size);
    return p;
}

Иди доказывай.

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

В рамках стандарта «определена» только обработка сигналов, а всё остальное - нет. Всё остальное, что система может делать с программой - нигде не описано. Она может делать всё что угодно.

Это какой-то тред-детектор «я-так-хочу»-программистов.

Они бы еще пожаловались, что в стандарте не описано, что во время исполнения программы могут отключить электричество или может сдохнуть железо. Как дети малые, ептыть.

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

И как ты узнавал, сколько памяти доступно?

static unsigned long long get_available_mem(void)
{
    return sysconf(_SC_AVPHYS_PAGES) * (unsigned long long) sysconf(_SC_PAGE_SIZE);
}

Но кэш не посчитается как available, а часто хотелось бы знать еще и его размер. Тут уже OS-specific API нужен. /proc можно читать.

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

Также могут существовать следующие значения, однако они могут быть не стандартизированы.

Не боишься, что в очередной реализации перестанет работать? Да и не факт, что если у тебя только что было 2ГБ свободно, пока ты вызовешь mmap, кто-то не отожрет часть!

Но спасибо, воткну в свои сниппеты. Заодно подумаю, что можно с /proc сделать.

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

Не боишься, что в очередной реализации перестанет работать?

Когда перестанет тогда и будет голова болеть.

Да и не факт, что если у тебя только что было 2ГБ свободно, пока ты вызовешь mmap, кто-то не отожрет часть!

В моём use case это неактуально, т.к. если ядро убъет просмотрщик картинок, туда ему и дорога. Я отслеживаю свободное ОЗУ, чтобы уступить память другим процессам: если памяти мало, то вместо того, чтобы принуждать ядро к выгрузке моего прикладного кэша в анонимной памяти на диск, я просто размапливаю часть кэша, и ядро получает свободные страницы сразу.

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

Вот такую бы политику говнюкам, которые браузеры пишут!

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

Т.е. На самом деле включение оверкоммита его выключает, а выключение - включает.

Его - это кого? Ты про какое поведение именно говоришь-то, дружок? В примере их два.

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

А еще приложения любят мапить в память файлы, часто очень большие, которые тоже не читаются во всех местах одновременно.

Сейчас прогресс дошёл до того, что если у вас память под буфер read/write выровнена по границе страницы, то кроме разницы в семантике доступа к этому буферу в плане производительности последовательного доступа разницы не будет.

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

Работает архиважная утилита на узле

А mlock() уже отменили?

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

Компилятор. Выкидывает запись памяти. По адресу, полученному из библиотечной функции с сайд-эффектами.

Ну да, прогресс и сюда добрался, если это не просто некая функция, а foo() __attribute__((malloc))+memset+free, то можно всё это и выкинуть. А вы думали __attribute__((malloc)) что означает? Доходит до эпичностей: https://bugs.launchpad.net/ubuntu/ source/gcc-4.7/ bug/1123588

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 3)
Ответ на: комментарий от Deleted

И ты не считаешь такое поведение песцом? Как бы ОС создавались так чтобы приложения не знали и не хотели знать, что у нее внутри, работали на виртуальном процессоре, виртуальной памяти и т. п. И ладно бы что-то крутое и низкоуровневое, но если в потроха лезет просмотрщик... что-то не так в королевстве.

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

Не считаю. С чего бы?

Прочитать jpeg и распаковать в битовую карту — это долго (относительно допустимых задержек гуя; допустим, jpeg реально большой). Поэтому я стараюсь поддерживать кэш распакованных картинок в ОЗУ.

Но только при условии, что памяти достаточно.

Если же памяти не достаточно, то выгружать распакованный битмап в своп, а потом загружать обратно — намного дольше, чем перечитать и распаковать файл заново. Поэтому кэш мы грохаем. Этим действием мы и другим приложениям помогаем, и себе облегчаем задачу, чтобы потом не тупить в свопе.

Это прикладная логика, её в ОС никак не засунешь.

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

Его - это кого?

Его - это того, о чём ты пытался транслировать. Пишешь оверкоммит + линукс в гугле и получаешь искомое, а именно то, о чём ты транслировал.

Ты про какое поведение именно говоришь-то, дружок?

Поведение чего, дружок?

В примере их два.

В каком таком примере?

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

В каком таком примере?

Здрасте приехали, в примере, что в исходном сообщении у топикстартера.

Поведение чего, дружок?

Это не оверкоммит. Я уже 20тысяч раз это объяснял. Это свойство реальности, а оверкоммит - это механизм именно подавления этого поведения.

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

Если есть подобное поведение - это явно баг. Тут есть фундаментальная проблема - эксперты не могут написать нормальный тест, а после делают какие-то далеко идущие выводы. Пример подобного теста есть выше. Это надо так же учитывать.

А так да, такая проблема( со странными оптимизациями) есть. И эту убогую моду инициировал шланг. Но там больше по части всяких уб.

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

Здрасте приехали, в примере, что в исходном сообщении у топикстартера.

Ну напиши - что там за два поведения такие. Я вижу одно.

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

Ты может и делаешь правильно. Неправильно что линукс заставляет это делать. Он протекает.

Это прикладная логика, её в ОС никак не засунешь

Можно и засунуть. Например, по аналогии со слабыми ссылками - будет «слабая» память, которую ОС может молча забрать пока она не заблочена.

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

Ты может и делаешь правильно. Неправильно что линукс заставляет это делать. Он протекает.

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

А сейчас, чем больше вся эта тема развивается, тем далее она отходит от этой шизофрении. И это правильно. Потому что железяка первична, реальность первична, а шизофрения - мусор. Хотя шизофрению выдают за некую модель, но в любом случае модель вторична и должно отображать в себе свойства реальности.

Можно и засунуть. Например, по аналогии со слабыми ссылками - будет «слабая» память, которую ОС может молча забрать пока она не заблочена.

Это противоречит текущим представлениям о памяти. Перед эти тебе надо их поменять. Это первое.

Второе - это сделать попросту невозможно. Почему подобная логика прозрачно работает для свопа/отображения файлов?

Всё очень просто - если ты отключаешь память, то куда сохранять её значения? В ситуации со свопом/файлом - это сохраняется в своп/файл. В этой же ситуации подобное поведение в принципе невозможно - у тебя будет пропадать данные.

Основная проблема не в линуксе - проблема в протухшем представлении и изначально убогих представлениях. И о работе железа и работе ОС. Нужно делать новые интерфейсы, а это потребует новой модели.

Это как в MT. Раньше модели кроме мутекса(а ещё раньше форка) ничего не знали, а сейчас есть прогресс. Точно так же как и ipc. рано или поздно всё это пойдёт будет развиваться.

Другое дело, что неосиляторы так и будут ныть и мечтать о том, что всё будет работать «само» и по волшебству. Такого, естественно, не будет никогда. Вам в пхп.

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

Как бы ОС создавались так чтобы приложения не знали и не хотели знать, что у нее внутри

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

работали на виртуальном процессоре, виртуальной памяти и т. п.

Работали. в 60годах. Вот с таким же успехом это может работать и сейчас, но это никому не надо.

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

Правильно. Что-бы нормально реализовать MT - надо лезть в кишки. Что-бы нормально реализовать кэширование и запись на диск - надо лезть в кишки. И так везде. Иного не дано.

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

Вот завтра им напиши, что реаллок не нужен. У них сломается шаблон. Напиши им, что вектор не потребляет до 50% лишней памяти. У них так же сломается шаблон. Расскажи им, что память не память - шаблон так же будет сломан.

И причина проста - неверные представления о реальности. Поэтому и приходиться страдать хернёй и выбирать «какой же коэффициент поставить вектору?». У них там целые баталии на этот счёт. Их не волнует, что ставь хоть х10 - это ничего не поменяет, кроме того, что станет только лучше.

Так всегда было, есть и будет. Хочешь написать нормальное, не дырявое говно - учитывай как можно больше нюансов. Либо используй то, где это уже учтено. Но опять же - не так просто натянуть эти нюансы на убогое представление. Это тупиковая ситуация.

Тебя всё равно надо будет менять своё представление - иначе ты просто не будет понимать зачем и что есть в новом маллоке.

Это как крестовики, у которых нет реаллока и они не понимает в чём проблема. В их представлении реаллок - это мемкопи+маллок+фри , что, естественно, не соответствует действительности.

И хоть что ты им говори - они ничего не поймут. ТАкие дела.

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

Вот завтра им напиши, что реаллок не нужен. У них сломается шаблон.

Ну так напиши, поломай мне шаблон. Я вот буквально час назад воспользовался realloc на своем 32 битном мипсе, а тут оказывается он не нужен.

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

Но в современных ОС не прижилось.

Зато прижилось вряд ли лучшее. Продакшен на яве — своя песочница с лимитами, как вышли за лимиты — запускается уборщик мусора, нешмогла — вертаем null и тут уже редко когда сами отказываемся от ресурсов, просто падаем. Зато никакого тебе oom_киллера, надо только поиграть с размерами свопа и лимитов: когда начинает недопустимо тормозить, ну и угадать с запасом, так как лимиты всё же плюс-минус километр.

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

Я вот буквально час назад воспользовался realloc на своем 32 битном мипсе, а тут оказывается он не нужен.

Проблема в том, что твой 32битный мипс не нужен. Это никакого отношения к теме не имеет. Его 32битность в 95% случаев мало на что влияет, да и говорилось тут про недырявое и быстрое, чего ни на каких мипсах, а уж тем более с реаллоком - не напишешь. Да и никого то, что не нужно волновать не должно.

Ну расскажи мне про свой кейс, который противоречит ненужности реаллока.

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