2009-10-12 1 views

ответ

4

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

Это не определено компилятором точно, а библиотекой.

Более типично фиксировать размер кучи в динамических языках с помощью GC. В C и C++ просто попросить ОС для большей памяти, так как это очевидно, когда вам это нужно. Как следствие, размер начальной кучи очень мал и является лишь решением реализации со стороны библиотеки распределения.

+0

Спасибо за ответ DigitalRoss. – 2009-10-12 05:05:26

+0

@ DigitalRoss: Не могли бы вы объяснить, что «это не определено компилятором точно, а библиотекой»? Я могу понять, что это не определяется компилятором, но как по библиотеке? Благодарю. – pierrotlefou

+0

В C и C++ политика кучи управляется событиями. Компилятор действительно генерирует вызовы распределения кучи в C++, а не в C. Когда компилятор генерирует вызов распределителю, он теперь находится в руках библиотеки, потому что вызывается фактическая функция. Эта функция пытается выделить из кучи (возможно, что-то было освобождено в последнее время), но если она терпит неудачу, она просто вызывает ОС, чтобы получить больше памяти для процесса в целом, и добавляет дополнительную память в кучу. – DigitalRoss

5

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

На платформах Unix это вдвойне верно. Даже большинство встроенных платформ Unix работают именно так.

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

В большинстве систем Unix существует жесткий предел того, сколько всего объема памяти может иметь процесс. Этот лимит может быть запрошен системным вызовом getrlimit. Соответствующей константой является RLIMIT_AS. Этот предел определяет максимальное количество страниц памяти, которые могут быть назначены процессу, и напрямую ограничивает доступное количество кучи.

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

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

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

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

0

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

Вы можете получить общее количество Availabe памяти в системном по:

cat /proc/meminfo | grep CommitLimit 
CommitLimit: 498080 kB 

Это CommitLimit Процент от со следующей формулой: CommitLimit = ('vm.overcommit_ratio' * Physical RAM) + Swap

Предположив свопа равна нулю, установив overcommit_ratio вас может настроить общую доступную память. Вы можете установить overcommit_ratio by:

sysctl -w vm.overcommit_ratio=60 

И важно отметить, что этот предел только придерживаться, если строгий учет overcommit включен (режим 2 в «vm.overcommit_memory»).. Это может быть установлено:

sysctl -w vm.overcommit_memory=2 

Вот ядро ​​document, что объяснить это хорошо.

+1

Это зависит от Linux и не относится к конкретной памяти процесса, а о том, как ядро ​​Linux обрабатывает виртуальную память через процессы. Традиционно управляемый сегмент данных Unix с ulimit. –

0

вы можете попытаться написать небольшую программу с помощью цикла while (true). после запуска «cat/proc/{pid}/maps» вы узнаете его начальный размер кучи.