Re[5]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.10.13 15:19
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Не вижу принципиальных преград. Например в D есть fiber'ы.


Основная преграда это востребованность.

I>>Судя по голосовалке на этом сайте файберы использовало ажно 7% программистов


EP>7% от чего? Какой вопрос был?


Вопрос простой — использовали ли вы файберы. Проголосовало достаточно большое количество людей, что бы делать какие то выводы.

EP>Я, например, сильно сомневаюсь что хотя бы 7% от всех C#'еров использует await, или даже yield.


Гораздо больше. Асинхронщина нужна и часто апи даже не подразумевает синхронных вызовов. Колбеки, rx, tpl — всё намного сложнее, чем авайт.
Re[6]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk Россия  
Дата: 05.10.13 16:01
Оценка:
Здравствуйте, Ikemefula, Вы писали:

EP>>Не вижу принципиальных преград. Например в D есть fiber'ы.

I>Основная преграда это востребованность.
I>>>Судя по голосовалке на этом сайте файберы использовало ажно 7% программистов
EP>>7% от чего? Какой вопрос был?
I>Вопрос простой — использовали ли вы файберы. Проголосовало достаточно большое количество людей, что бы делать какие то выводы.

IMHO — если 7% реально использовало, то это даже хорошая востребованность
А если учесть то, что появилась реально удобная и кросс-платформенная реализация, причём на самом видном месте — то процент будет только расти.

EP>>Я, например, сильно сомневаюсь что хотя бы 7% от всех C#'еров использует await, или даже yield.

I>Гораздо больше.

Не верю. await появился чуть больше года назад, я сомневаюсь что на VS2012 перешло много контор.
Re[7]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.10.13 17:35
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>IMHO — если 7% реально использовало, то это даже хорошая востребованность

EP>А если учесть то, что появилась реально удобная и кросс-платформенная реализация, причём на самом видном месте — то процент будет только расти.

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

EP>>>Я, например, сильно сомневаюсь что хотя бы 7% от всех C#'еров использует await, или даже yield.

I>>Гораздо больше.

EP>Не верю. await появился чуть больше года назад, я сомневаюсь что на VS2012 перешло много контор.


Нет особых проблем в переходе на нужный фремворк, обратная совместимость почти идеальная. Авайт очень сильно облегчает работу и позволяет убрать вагоны кода.
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk Россия  
Дата: 05.10.13 18:28
Оценка:
Здравствуйте, Ikemefula, Вы писали:

EP>>IMHO — если 7% реально использовало, то это даже хорошая востребованность

EP>>А если учесть то, что появилась реально удобная и кросс-платформенная реализация, причём на самом видном месте — то процент будет только расти.
I>Сильно вряд ли.

Согласен, но раза в 1.5 — спокойно.

I>Основной тренд это мощные локальные фичи, навроде авайта.


await и yield — это реально удобные feature, и у них очень много общего.
Нужно пытаться их обобщать — в духе C++ вводить features, которые не ограниченны несколькими конкретными применениями. Также library-only feature предпочтительней чем требующие изменения в самом языке. И один из вариантов это stackful coroutine — на основе которой реализуются и await, и yield, и многие другие features, которая реализуется как library-only.

I>Основная проблема не в синтексисе и удобстве а в сложности самой концепции — кооперативной многозадачности.


Coroutine это далеко не только кооперативная многозадачность.

I>Авайт очень сильно облегчает работу и позволяет убрать вагоны кода.


Согласен, но это не означет что все C#'исты кинулись его изучать. Многие годами ничего не изучают, не следят за новыми фичами и т.п. И как-то не верится в то, что "гораздо больше 7% C#'еров используют годовалую фичу".
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Jack128  
Дата: 05.10.13 19:49
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Нет особых проблем в переходе на нужный фремворк, обратная совместимость почти идеальная.

наверно из-за идеальной совместимости тут, на рсдн, появляются темы какого гуя у мя в 4,0 работает, а в 4,5 не работает..
Re[9]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 06.10.13 09:18
Оценка:
Здравствуйте, Jack128, Вы писали:

I>>Нет особых проблем в переходе на нужный фремворк, обратная совместимость почти идеальная.

J>наверно из-за идеальной совместимости тут, на рсдн, появляются темы какого гуя у мя в 4,0 работает, а в 4,5 не работает..

Слово "почти" перевести что ли ?
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 28.11.13 20:57
Оценка:
Здравствуйте, enji, Вы писали:

E>В настоящей многопоточности нужна синхронизация, а в корутинах с этим все проще.

E>Так что если задача позволяет — часто корутины удобнее...

Здесь она тоже нужна, просто ты можешь вместо синхронизации — переключать нужным образом корутины. Но эти самые корутины тоже могут изменять общие данные. Настоящие потоки, кстати, имеют очень много приятных свойств, например, планировщик ОС пытается предотвращать starvation и priority inversion, планировщик меняет приоритеты потоков динамически, снижая приоритет CPU bound потоков и повышая приоритет I/O bound потоков, для того, чтобы повысить отзывчивость системы. В общем, когда люди берутся писать код на корутинах или асинхронный код на boost.asio — они часто впервые в жизни сталкиваются со всеми этими проблемами
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 28.11.13 21:09
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе).


ОС?
Re[4]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk Россия  
Дата: 28.11.13 21:47
Оценка:
Здравствуйте, Lazin, Вы писали:

EP>>Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе).

L>ОС?

Windows 7 x64, MSVC2010SP1 x64, Boost 1.53. Должно работать и на других OS, но не проверял.
Re[5]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 29.11.13 08:13
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали

EP>Windows 7 x64, MSVC2010SP1 x64, Boost 1.53. Должно работать и на других OS, но не проверял.


А сколько на той машине памяти и свопа и какой размер стока пришлось поставить?
Re[6]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk Россия  
Дата: 29.11.13 11:48
Оценка:
Здравствуйте, Lazin, Вы писали:

EP>>Windows 7 x64, MSVC2010SP1 x64, Boost 1.53. Должно работать и на других OS, но не проверял.

L>А сколько на той машине памяти и свопа и какой размер стока пришлось поставить?

Памяти 6GiB, свопа нет. Размер стэка 10KiB.
#include <boost/container/vector.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/coroutine/all.hpp>
#include <exception>
#include <iostream>

using namespace boost;
using namespace std;

unsigned long counter = 0;

int main()
try
{
    const auto n = 200000;
    const auto stack = 10 * (1u<<10);

    typedef coroutines::coroutine< void() > Coro;
    container::vector<Coro> fibers;
    fibers.reserve(n);
    for(auto i=0; i!=n; ++i)
    {
        fibers.emplace_back([](Coro::caller_type &yield)
        {
            while(true)
            {
                ++counter;
                yield();
            }
        }, coroutines::attributes(stack));
    }

    while(true)
    {
        for_each(fibers, [](Coro &yield)
        {
            yield();
        });
        cout << counter << endl;
    }
}
catch(const std::exception &e)
{
    cout << e.what() << endl;
}
Но там ещё много других настроек, например нужно ли сохранять fpu регистры и т.п. 200k это не предел, например только изменив стэк на 1KiB получилось сходу запустить 400k корутин.
Re[7]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 29.11.13 22:23
Оценка: 21 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Памяти 6GiB, свопа нет. Размер стэка 10KiB.


И всего 200К корутин
Фишка async в F#/C# в том, что можно особо не думать о ресурсах, просто запускать таск на каждый чих и все будет хорошо. Это делает возможным несколько иной стиль программирования. Допустим нам нужно обработать каждый файл в директории, рекурсивно, просто запускаем таск на каждый файл или директорию, а пулл потоков будет их постепенно выполнять, пока они не закончатся. Причем таски в C# могут порождать другие таски и зависеть друг от друга. А под капотом там task stealing планировщик, как в Cilk. В boost.coroutine же нет никакого планировщика, AFAIK. В общем, на мой взгляд их не очень корректно сравнивать.

Также стоит обратить внимание на то, что ограничением в этом эксперименте является количество вирт. памяти, выделенной под стек, не количество физической памяти (там скорее всего выделяется по одной странице физ. памяти на стек). В винде есть глобальное ограничение на количество выделенной виртуальной памяти для всех процессов — commit limit. По умолчанию commit limit = размер своп файла + общий объем физичской памяти — некоторое заранее неизвестное количество памяти под нужны системы. Если процесс вылез за commit limit — он получит ООМ, даже если свободной физической памяти много. Это называется overcommit и в винде он, AFAIK, запрещен. Может быть его можно как-то разрешить, я не знаю. В linux overcommit по умолчанию разрешен, но там есть эвристический алгоритм, который может прибить процесс, ушедший в overcommit. Также, overcommit там может быть разрешен полностью или запрещен как в винде настройками. В общем, виртуальное адресное пространство — вещь не бесконечная и может быть исчерпано очень быстро. Это несколько ограничивает применимость подобных корутин на практике.
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk Россия  
Дата: 29.11.13 22:58
Оценка:
Здравствуйте, Lazin, Вы писали:

EP>>Памяти 6GiB, свопа нет. Размер стэка 10KiB.

L>И всего 200К корутин

Я уверен что можно и больше — но нужно играться с настройками, сейчас мне это не настолько интересно.

L>Фишка async в F#/C# в том, что можно особо не думать о ресурсах, просто запускать таск на каждый чих и все будет хорошо.


У stackless корутин безусловно есть свою плюсы. Вот тут описывал
Автор: Evgeny.Panasyuk
Дата: 19.11.13
некоторые пункты.
И сейчас stackless корутины доступны для C++, только в весьма ограниченном виде (я даже как-то делал мини реализацию await в таком stackless стиле).

L>А под капотом там task stealing планировщик, как в Cilk. В boost.coroutine же нет никакого планировщика, AFAIK. В общем, на мой взгляд их не очень корректно сравнивать.


Планировщик это вообще ортогональная вещь.
await умеет работать с разными планировщиками, syncronization и execution контексты (или как-то так) — настраиваемые. Он может работать и с самодельным пулом потоков и с чем-то на подобие Boost.Asio в одном потоке. Точно также и корутины могут работать с разными планировщиками — можно с Asio использовать, а можно например с GUI Message Loop.

L>В общем, виртуальное адресное пространство — вещь не бесконечная и может быть исчерпано очень быстро. Это несколько ограничивает применимость подобных корутин на практике.


У них аллокатор стэка настраивается.
Если нужна куча долгоживущих корутин — то достаточно применить простеший аллокатор, который съест большой блок, и для аллокации просто будет делать free += requested;
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: alex_public  
Дата: 30.11.13 00:13
Оценка:
Здравствуйте, Lazin, Вы писали:

L>Фишка async в F#/C# в том, что можно особо не думать о ресурсах, просто запускать таск на каждый чих и все будет хорошо.


Обожаю эти фразы в стиле C#/Java.

L>Это делает возможным несколько иной стиль программирования. Допустим нам нужно обработать каждый файл в директории, рекурсивно, просто запускаем таск на каждый файл или директорию, а пулл потоков будет их постепенно выполнять, пока они не закончатся. Причем таски в C# могут порождать другие таски и зависеть друг от друга. А под капотом там task stealing планировщик, как в Cilk. В boost.coroutine же нет никакого планировщика, AFAIK. В общем, на мой взгляд их не очень корректно сравнивать.


Единственное преимущество .net в данном случае — это единство синтаксиса. Т.е. запись при просто асинхронной работе или при пуле потоков и т.п. выглядит практически одинаково. А в C++ это вообще отдельные сущности. Т.е. хочется асинхронности — ставим одну библиотеку, хочется пул потоков — ставим другую, хочется одно поверх другого — сопрягаем их вместе. Естественно при этом даётся больше возможностей, чем в .net варианте, но и единого универсального синтаксиса естественно нет. Какой вариант лучше, думаю дело личных вкусов и стилей...

L>Также стоит обратить внимание на то, что ограничением в этом эксперименте является количество вирт. памяти, выделенной под стек, не количество физической памяти (там скорее всего выделяется по одной странице физ. памяти на стек). В винде есть глобальное ограничение на количество выделенной виртуальной памяти для всех процессов — commit limit. По умолчанию commit limit = размер своп файла + общий объем физичской памяти — некоторое заранее неизвестное количество памяти под нужны системы. Если процесс вылез за commit limit — он получит ООМ, даже если свободной физической памяти много. Это называется overcommit и в винде он, AFAIK, запрещен. Может быть его можно как-то разрешить, я не знаю. В linux overcommit по умолчанию разрешен, но там есть эвристический алгоритм, который может прибить процесс, ушедший в overcommit. Также, overcommit там может быть разрешен полностью или запрещен как в винде настройками. В общем, виртуальное адресное пространство — вещь не бесконечная и может быть исчерпано очень быстро. Это несколько ограничивает применимость подобных корутин на практике.


На практике? ) Вышеописанное соответствует очень узкой категории задач, типа написания высоконагруженного сервера на множество клиентов. И для таких задач есть свой набор известных по этой области решений.
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Cyberax Марс  
Дата: 30.11.13 00:19
Оценка:
Здравствуйте, Lazin, Вы писали:

L> В linux overcommit по умолчанию разрешен, но там есть эвристический алгоритм, который может прибить процесс, ушедший в overcommit.

Не будет. Пока процесс не начнёт трогать страницы — можно хоть 100Гб распределять.
cyberax@virtlin:~$ cat test.c 
#include <stdio.h>
#include <malloc.h>

int main()
{
    void * ptr = malloc(1024LL*1024*1024*60);
    if (ptr)
        printf("OK\n");
}
cyberax@virtlin:~$ gcc test.c 
cyberax@virtlin:~$ ./a.out 
OK
cyberax@virtlin:~$ free -m
             total       used       free     shared    buffers     cached
Mem:          4606       1999       2607          0        614        887
-/+ buffers/cache:        497       4108
Swap:         4765         12       4753
Sapienti sat!
Re[9]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk Россия  
Дата: 30.11.13 00:29
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>Памяти 6GiB, свопа нет. Размер стэка 10KiB.

L>>И всего 200К корутин
EP>Я уверен что можно и больше — но нужно играться с настройками, сейчас мне это не настолько интересно.
[...]
L>>В общем, виртуальное адресное пространство — вещь не бесконечная и может быть исчерпано очень быстро. Это несколько ограничивает применимость подобных корутин на практике.
EP>У них аллокатор стэка настраивается.
EP>Если нужна куча долгоживущих корутин — то достаточно применить простеший аллокатор, который съест большой блок, и для аллокации просто будет делать free += requested;

Собственно тест на таком простом аллокатаре выдаёт 400k корутин по 10KiB стэка (~3.8GiB только под стэки). Всего на систему памяти 6GiB, без swap (всякие фоновые программы работают и т.п.):
#include <boost/container/vector.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/coroutine/all.hpp>
#include <exception>
#include <iostream>

using namespace boost;
using namespace std;

container::vector<char> memory(size_t(1) << 32);
auto last_free = memory.data();

struct stack_allocator
{
    void *allocate(size_t size) const
    {
        return last_free += size;
    }
    void deallocate(void * vp, size_t size) const {}
};

unsigned long counter = 0;

int main()
try
{
    const auto n = 400000;
    const auto stack = 10 * (1u<<10);

    typedef coroutines::coroutine< void() > Coro;
    container::vector<Coro> fibers;
    fibers.reserve(n);
    for(auto i=0; i!=n; ++i)
    {
        fibers.emplace_back([](Coro::caller_type &yield)
        {
            while(true)
            {
                ++counter;
                yield();
            }
        }, coroutines::attributes(stack), stack_allocator());
    }
    cout << "allocated for stacks: " << (last_free - memory.data())/(1u << 20) << endl;

    while(true)
    {
        for_each(fibers, [](Coro &yield)
        {
            yield();
        });
        cout << counter << endl;
    }
}
catch(const std::exception &e)
{
    cout << e.what() << endl;
}
При желании можно ещё больше выжать.
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk Россия  
Дата: 30.11.13 00:51
Оценка:
Здравствуйте, Lazin, Вы писали:

L>Также стоит обратить внимание на то, что ограничением в этом эксперименте является количество вирт. памяти, выделенной под стек, не количество физической памяти (там скорее всего выделяется по одной странице физ. памяти на стек). В винде есть глобальное ограничение на количество выделенной виртуальной памяти для всех процессов — commit limit. По умолчанию commit limit = размер своп файла + общий объем физичской памяти — некоторое заранее неизвестное количество памяти под нужны системы. Если процесс вылез за commit limit — он получит ООМ, даже если свободной физической памяти много. Это называется overcommit и в винде он, AFAIK, запрещен. Может быть его можно как-то разрешить, я не знаю.


#include <Windows.h>
#include <iostream>
#include <cstddef>

int main()
{    
    using namespace std;

    for(auto i=0; i!=32; ++i)
        cout << VirtualAlloc(0, size_t(1) << 36, MEM_RESERVE, PAGE_READWRITE) << endl;
}

000000013FCF0000
000000113FCF0000
000000213FCF0000
000000313FCF0000
000000413FCF0000
000000513FCF0000
000000613FCF0000
000000713FCF0000
000000813FCF0000
000000913FCF0000
000000A13FCF0000
000000B13FCF0000
000000C13FCF0000
000000D13FCF0000
000000E13FCF0000
000000F13FCF0000
000001013FCF0000
000001113FCF0000
000001213FCF0000
000001313FCF0000
000001413FCF0000
000001513FCF0000
000001613FCF0000
000001713FCF0000
000001813FCF0000
000001913FCF0000
000001A13FCF0000
000001B13FCF0000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
Никаких настроек не менял
Re[9]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 30.11.13 08:57
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Lazin, Вы писали:


EP>>>Памяти 6GiB, свопа нет. Размер стэка 10KiB.

L>>И всего 200К корутин

EP>Я уверен что можно и больше — но нужно играться с настройками, сейчас мне это не настолько интересно.

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

EP>У stackless корутин безусловно есть свою плюсы. Вот тут описывал
Автор: Evgeny.Panasyuk
Дата: 19.11.13
некоторые пункты.

EP>И сейчас stackless корутины доступны для C++, только в весьма ограниченном виде (я даже как-то делал мини реализацию await в таком stackless стиле).

Я не утверждаю что оно не нужно, просто у корутин и async/await несколько разные потенциальные области применения. Посему поддержка async/await в стандарте это гуд, независимо от того, есть ли корутины в стандартной библиотеке или нет.
Re[9]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 30.11.13 09:02
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>
EP>#include <Windows.h>
EP>#include <iostream>
EP>#include <cstddef>

EP>int main()
EP>{    
EP>    using namespace std;

EP>    for(auto i=0; i!=32; ++i)
EP>        cout << VirtualAlloc(0, size_t(1) << 36, MEM_RESERVE, PAGE_READWRITE) << endl;
EP>}
EP>

EP>
EP>000000013FCF0000
EP>000000113FCF0000
EP>000000213FCF0000
EP>000000313FCF0000
EP>000000413FCF0000
EP>000000513FCF0000
EP>000000613FCF0000
EP>000000713FCF0000
EP>000000813FCF0000
EP>000000913FCF0000
EP>000000A13FCF0000
EP>000000B13FCF0000
EP>000000C13FCF0000
EP>000000D13FCF0000
EP>000000E13FCF0000
EP>000000F13FCF0000
EP>000001013FCF0000
EP>000001113FCF0000
EP>000001213FCF0000
EP>000001313FCF0000
EP>000001413FCF0000
EP>000001513FCF0000
EP>000001613FCF0000
EP>000001713FCF0000
EP>000001813FCF0000
EP>000001913FCF0000
EP>000001A13FCF0000
EP>000001B13FCF0000
EP>0000000000000000
EP>0000000000000000
EP>0000000000000000
EP>0000000000000000
EP>
Никаких настроек не менял


Ну я пару лент назад пытался переписать кое что на файберы, тогда еще не было boost.coroutine, поэтому все строилось на Win32 API. User mode scheduling в винде тогда тоже еще не было. В общем, я именно с этим ограничением и столкнулся. Мне не удавалось создать больше чем swap size + physical memory size стеков. С помощью изменения размера стека мне удалось запустить больше файберов, но все равно этого не хватало, поэтому пришлось продолжить использовать event based архитектуру. Потом я прочитал у Русиновича о том, что каждой странице вирт. памяти в винде должна быть сопоставлена либо страница физической памяти, либо страница в page-файле.
Re[9]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 30.11.13 09:04
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, Lazin, Вы писали:


L>> В linux overcommit по умолчанию разрешен, но там есть эвристический алгоритм, который может прибить процесс, ушедший в overcommit.

C>Не будет. Пока процесс не начнёт трогать страницы — можно хоть 100Гб распределять.

Мой поинт не в том, что нельзя, а в том, что такой подход не универсален, так как требует чтобы система была настроена определенным образом, а в linux можно запретить overcommit, насколько я знаю.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.