LINUX.ORG.RU

История изменений

Исправление Moisha_Liberman, (текущая версия) :

Вы говорите про какие-то древние Юниксы в которых куча работает через sbrk.

Пример:

#include <stdlib.h>

int main() {
	int *ptr = (int *)malloc(1024 * sizeof(int));
	return 0;
}

Далее очевидно что делаем gcc test.c; strace ./a.out. Смотрим вывод:

strace ./a.out 
execve("./a.out", ["./a.out"], 0x7ffebb592060 /* 53 vars */) = 0
brk(NULL)                               = 0x55d8c24eb000

А вот остальное (загрузка и выгрузка разделяемых библиотек) да, через mmap()/munmap(). Ну просто потому, что размеры библиотек такие, что ну его на фиг их по-другому грузить.

В современных системах куча работает через mmap и адресное пространство освобождается после вызова free, правда не сразу.

Оно будет освобождено только после завершения программы. Либо программа завершится сама и по-хорошему, либо к программе система вышлет ООМ-киллера (если программа вообще «берега попутала» и сожрала недопустимо много памяти на недопустимо долгий срок, это всё настраивается). Альтернатив нет.

И нет. mmap() и malloc()/free() это разные вещи (я об этом и написал) и mmap на расширение кучи ни как не влияет.

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

Да, поэтому я сразу написал TC про jemalloc и tcmalloc.

Языки со сборкой мусора почти всегда делают свою кучу на основе mmap.

А вот это вот сразу так далеко, что отсюда не видно даже. =))) Обычно С-программисты всё-таки, умнее железа и софта и сами знают как грамотно использовать распределение памяти. Вообще, на мой взгляд, все попытки изобрести новые, безопасные языки программирования, да ещё и со сборкой мусора, которая работает сама по себе, вне контроля программиста, это попытка защитить идиотов от самих себя. Нет, не защитите. Любые языки со сборкой мусора это АдЪ, треш, угар и немного, буквально для придания чуточки пикантности, содомiя. В одном флаконе.

Программа может использовать любую память как стек.

Фсмысле??? Нет, не может. Сегмент стека программы это сегмент стека программы. И вот не надо его путать с ADT (abstract data type) под названием stack. Такой абстрактный тип данных Вы можете реализовать в куче или в сегменте стека. Но к stack segment приложения этот ADT не имеет ровным счётом никакого отношения.

Для работы со stack segment есть getrlimit(), setrlimit(), alloca(), либо динамические массивы. Больше никаких средств в Linux не предусмотрено.

Есть библиотеки короутин которые выделяют стековую память через malloc/mmap и напрямую задают регистр SP.

Как корутины (про них ещё Дональд Кнут в незапамятно-лохматом году писал в своей книге «The Art of Computer Programming», если что), так и фидеры и green threads это потоки исполнения в userspace. Т.е., ядро об этих потоках вообще ничего не знает и знать не желает. Рекомендую к прочтению и к ознакомлению парочку из вариантов реализации – GNU Pth и protothreads.

Но всё это не отменяет того факта, что ни зелёные нитки, ни корутины, ни фидеры нельзя и близко сравнивать с native process/pthreads просто потому, что система про эти ухищрения не знает ничего и все эти решения ни как не обрабатываются тем же системным планировщиком. Т.е., если программист сам использует такие решения, то он и сам должен отвечать за работу такого решения внутри своего приложения (потока или процесса, не важно) – отслеживать состояния и переключать контексты например. И да, стек у них тоже один. Но извините это не отдельные потоки. Для системы.

Защитную страницу тоже можно сделать через mmap/mprotect.

Можно. Но не факт то нужно. =)

И не забывайте что языки программирования не ограничиваются C/C++.

Я не думаю что в новых, модных и более безопасных языках чем С, придумали новый API системы. Просто, от программиста этот самый API, лежащий на самом нижнем уровне абстракций, все эти сегменты виртуального адресного пространства процесса, все эти сисколлы, надёжно скрыты за слоями абстракций более высокого уровня. И тут вопрос только – что и от кого мы защищаем. Идиота простите, «программиста» от системы или систему от… программиста? =)))

Исправление Moisha_Liberman, :

Вы говорите про какие-то древние Юниксы в которых куча работает через sbrk.

Пример:

#include <stdlib.h>

int main() {
	int *ptr = (int *)malloc(1024 * sizeof(int));
	return 0;
}

Далее очевидно что делаем gcc test.c; strace ./a.out. Смотрим вывод:

strace ./a.out 
execve("./a.out", ["./a.out"], 0x7ffebb592060 /* 53 vars */) = 0
brk(NULL)                               = 0x55d8c24eb000

А вот остальное (загрузка и выгрузка разделяемых библиотек) да, через mmap()/munmap(). Ну просто потому, что размеры библиотек такие, что ну его на фиг их по-другому грузить.

В современных системах куча работает через mmap и адресное пространство освобождается после вызова free, правда не сразу.

Оно будет освобождено только после завершения программы. Либо программа завершится сама и по-хорошему, либо к программе система вышлет ООМ-киллера (если программа вообще «берега попутала» и сожрала недопустимо много памяти на недопустимо долгий срок, это всё настраивается). Альтернатив нет.

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

Да, поэтому я сразу написал TC про jemalloc и tcmalloc.

Языки со сборкой мусора почти всегда делают свою кучу на основе mmap.

А вот это вот сразу так далеко, что отсюда не видно даже. =))) Обычно С-программисты всё-таки, умнее железа и софта и сами знают как грамотно использовать распределение памяти. Вообще, на мой взгляд, все попытки изобрести новые, безопасные языки программирования, да ещё и со сборкой мусора, которая работает сама по себе, вне контроля программиста, это попытка защитить идиотов от самих себя. Нет, не защитите. Любые языки со сборкой мусора это АдЪ, треш, угар и немного, буквально для придания чуточки пикантности, содомiя. В одном флаконе.

Программа может использовать любую память как стек.

Фсмысле??? Нет, не может. Сегмент стека программы это сегмент стека программы. И вот не надо его путать с ADT (abstract data type) под названием stack. Такой абстрактный тип данных Вы можете реализовать в куче или в сегменте стека. Но к stack segment приложения этот ADT не имеет ровным счётом никакого отношения.

Для работы со stack segment есть getrlimit(), setrlimit(), alloca(), либо динамические массивы. Больше никаких средств в Linux не предусмотрено.

Есть библиотеки короутин которые выделяют стековую память через malloc/mmap и напрямую задают регистр SP.

Как корутины (про них ещё Дональд Кнут в незапамятно-лохматом году писал в своей книге «The Art of Computer Programming», если что), так и фидеры и green threads это потоки исполнения в userspace. Т.е., ядро об этих потоках вообще ничего не знает и знать не желает. Рекомендую к прочтению и к ознакомлению парочку из вариантов реализации – GNU Pth и protothreads.

Но всё это не отменяет того факта, что ни зелёные нитки, ни корутины, ни фидеры нельзя и близко сравнивать с native process/pthreads просто потому, что система про эти ухищрения не знает ничего и все эти решения ни как не обрабатываются тем же системным планировщиком. Т.е., если программист сам использует такие решения, то он и сам должен отвечать за работу такого решения внутри своего приложения (потока или процесса, не важно) – отслеживать состояния и переключать контексты например. И да, стек у них тоже один. Но извините это не отдельные потоки. Для системы.

Защитную страницу тоже можно сделать через mmap/mprotect.

Можно. Но не факт то нужно. =)

И не забывайте что языки программирования не ограничиваются C/C++.

Я не думаю что в новых, модных и более безопасных языках чем С, придумали новый API системы. Просто, от программиста этот самый API, лежащий на самом нижнем уровне абстракций, все эти сегменты виртуального адресного пространства процесса, все эти сисколлы, надёжно скрыты за слоями абстракций более высокого уровня. И тут вопрос только – что и от кого мы защищаем. Идиота простите, «программиста» от системы или систему от… программиста? =)))

Исходная версия Moisha_Liberman, :

Нет.

Вы говорите про какие-то древние Юниксы в которых куча работает через sbrk.

Пример:

#include <stdlib.h>

int main() {
	int *ptr = (int *)malloc(1024 * sizeof(int));
	return 0;
}

Далее очевидно что делаем gcc test.c; strace ./aout. Сотрим вывод:

strace ./a.out 
execve("./a.out", ["./a.out"], 0x7ffebb592060 /* 53 vars */) = 0
brk(NULL)                               = 0x55d8c24eb000

А вот остальное (загрузка и выгрузка разделяемых библиотек) да, через mmap()/munmap(). Ну просто потому, что размеры библиотек такие, что ну его на фиг их по-другому грузить.

В современных системах куча работает через mmap и адресное пространство освобождается после вызова free, правда не сразу.

Оно будет освобождено только после завершения программы. Либо программа завершится сама и по-хорошему, либо у программе система вышлет ООМ-киллера (если программа вообще «берега попутала» и сожрала недопустимо много памяти на недопустимо долгий срок, это всё настраивается). Альтернатив нет.

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

Да, поэтому я сразу написал TC про jemalloc и tcmalloc.

Языки со сборкой мусора почти всегда делают свою кучу на основе mmap.

А вот это вот сразу так далеко, что отсюда не видно даже. =))) Обычно С-программисты всё-таки, умнее железа и софта и сами знают как грамотно использовать распределение памяти. Вообще, на мой взгляд, все попытки изобрести новые, безопасные языки программирования, да ещё и со сборкой мусора, которая работает сама по себе, вне контроля программиста, это попытка защитить идиотов от самих себя. Нет, не защитите. Любые языки со сборкой мусора это АдЪ, треш, угар и немного, буквально для придания чуточки пикантности, содомiя. В одном флаконе.

Программа может использовать любую память как стек.

Фсмысле??? Нет, не может. Сегмент стека программы это сегмент стека программы. B вот не надо его путать с ADT (abstract data type) под названием stack. Такой абстрактный тип данных Вы можете реализовать в куче или в сегменте стека. Но к stack segment приложения этот ADT не имеет ровным счётом никакого отношения.

Для работы со stack segment есть getrlimit(), setrlimit(), alloca(), либо динамические массивы. Больше никаких средств в Linux не предусмотрено.

Есть библиотеки короутин которые выделяют стековую память через malloc/mmap и напрямую задают регистр SP.

Как корутины (про них ещё Дональд Кнут в незапамятно-лохматом году писал в своей книге «The Art of Computer Programming», если что), так и фидеры и green threads это потоки исполнения в userspace. Т.е., ядро об этих потоках вообще ничего не знает и знать не желает. Рекоммендую к прочтению и к ознакомлению парочку из вариантов реализации – GNU Pth и protothreads.

Но всё это не отменяет того факта, что ни зелёные нитки, ни корутины, ни фидеры нельзя и близко сравнивать с native process/pthreads просто потому, что система про эти ухищрения не знает ничего и все эти решения ни как не обрабатываются тем же системным планировщиком. Т.е., если программист сам использует такие решения, то он и сам должен отвечать за работу такого решения внутри своего приложения (потока или процесса, не важно) – отслеживать состояния и переключать контексты например. И да, стек у них тоже один. Но извините это не отдельные потоки. Для системы.

Защитную страницу тоже можно сделать через mmap/mprotect.

Можно. Но не факт то нужно. =)

И не забывайте что языки программирования не ограничиваются C/C++.

Я не думаю что в новых, модных и более безопасных языках чем С, придумали новый API системы. Просто, от программиста этот самый API, лежащий на самом нижнем уровне абстракций, все эти сегменты виртуального адресного пространства процесса, все эти сисколлы, надёжно скрыты за слоями абстракций более высокого уровня. И тут вопрос только – что и от кого мы защищаем. Идиота простите, «программиста» от системы или систему от… программиста? =)))