2010-02-12 1 views
24

Это общая практика для проверки NULL (независимо от того, успешно распределенная памяти) после таНоса(), некоторые вещи, какЕсть ли необходимость проверить на NULL после выделения памяти, когда ядро ​​использует overcommit модуля памяти

void *ptr = malloc(10);  
if (ptr != NULL) { 
    // do some thing usefull 
} else { 
// no memory. safely return/throw ... 
} 

с включенной памятью ядра в ядре, есть ли шанс получить NULL? Должен ли я следовать практике религиозной проверки NULL для каждого распределения? Будет ли malloc возвращать NULL, несмотря на агрессивный механизм overcommit (я думаю, значение 1)?

На самом деле ядро ​​Android использует overcommit памяти (не уверен в значении, хотел бы знать его (превышение значения) и его значение). Некоторый код исходного кода (C/C++) в Android (может быть сторонним) не проверяет наличие NULL и не вылавливает bad_alloc после выделения. Я что-то упускаю?

Есть некоторые темы в SO относительно памяти overcommit, но никто из них не разрешил мое замешательство.

EDIT: Если применяется агрессивный сверхкомпьютер, то NULL не будет возвращен (предположение 1). Когда нет физической памяти и не пытается получить доступ к выделенной памяти (запись в выделенную память), OOM убьет некоторый процесс и распределит память для приложения, пока он не будет убит по очереди (предположение 2). В любом случае я не вижу необходимости в том, чтобы набрать NULL (выделение памяти или удаление процесса). Я прямо в своих предположениях?
Переносимость не вызывает беспокойства по этому вопросу.

+0

Что такое * overcommit memory *? Если вы говорите о файле страницы на устройстве, то NO, Android (и другие мобильные устройства) обычно не используют файл страницы. Это потому, что записи будут изнашивать NAND или флэш-память SSD раньше. Или вы говорите о симуляторах и гипервизорах? – jww

ответ

34

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

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

+5

+1 для указания «фрагментации». – FL4SOF

+0

Если вы попытаетесь выделить 1M памяти, а malloc возвращает NULL из-за фрагментации, как вы начнете обрабатывать этот случай? Что делать, если вы попытаетесь выделить большую часть памяти из-за ошибки, разве вам не удастся сбой и получить дамп ядра, чем чисто выйти или иначе обойти ошибку? – Skrymsli

+0

@Skrymsli: Это зависит от приложения и среды. Если «сбой» немедленно требуется, я предпочел бы явный «прервать», а не выполнять неопределенное количество времени, пока некоторое использование нулевого указателя не приведет к сбою в качестве побочного эффекта. Некоторые приложения могут удалять много выделенной памяти и каким-то образом восстанавливаться. Однако предпосылка вопроса состоит в том, что я должен проверить значение null, потому что, конечно, с чрезмерной фиксацией никогда не произойдет, что я утверждаю, это неверно. –

8

Вы должны проверить возвращаемое значение для NULL каждые раз. Любая функция библиотеки может выйти из строя. Даже fclose() do (при отключенном общем доступе NFS и ошибке от fclose файла NFS означает, что данные не были сохранены).

Большая часть программного обеспечения плохо написана и не содержит всех проверок.

malloc не может вернуть что-либо, кроме NULL или указателя. Все или ничего. Вы не можете получить 1 байт от malloc, если вы попросили 10.

+0

мой вопрос заключается не в реализации malloc, а в использовании malloc. с включенной поддержкой overcommit, вероятность получения NULL (теоретически) меньше, и это очевидно в некоторых источниках android c/C++ framework, которые не выполняют эту проверку после распределения. – FL4SOF

+0

С overcommit mallic провалится дальше. http://opsmonkey.blogspot.com/2007/01/linux-memory-overcommit.html Как правило, malloc не прерывается, когда память доступна, а ulimit не достигнут. – osgx

+0

«С overcommit malloc не удастся». Я считаю, что это неверное предположение, пожалуйста, просмотрите ссылку, которую вы упомянули. В нем написано: demo1: память malloc и не использует его: выделено 1.4TB, убито убийцей OOM demo2: память malloc и использовать его сразу: выделено 7,8 ГБ, убито убийцей OOM (процесс убит убийцей OOM, а не случай сбоя malloc). – FL4SOF

2

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

Этот следующий сегмент кода ниже показано, как проверить, если вызов malloc работал или нет ... операции

 
void *ptr = malloc(10); 
if (ptr != NULL){ 
    /* Do something here with ptr */ 
}else{ 
    /* Do something here if it fails */ 
} 

файлов, операции с памятью на имя, но мало кто будет возвращать NULL при неудаче.

Надеюсь, это поможет, С уважением, Tom.

+0

'сегмент кода опасное предположение' вы можете объяснить? «Android middleware» извиняется за то, что он был таким общим, «некоторый код исходного кода кадра (C/C++) в android« я должен сказать ». Я отредактирую свой вопрос. – FL4SOF

+0

@ FL4SOF: см. Отредактированный ответ ... – t0mm13b

+0

Может быть, это не в тему, но мне любопытно, какое действие вы предпринимаете в/* Что-то здесь, если оно терпит неудачу */section? Предположительно, все, что вы делаете, не сможет выделить память, если вы действительно не можете выделить 10 байт памяти. Вы можете попасть в бесконечный цикл проверки нехватки памяти и обращения с ней. Вы просто выходите? Это лучше, чем сбой на нулевом разыменовании? – Skrymsli

-4

Нет, нет необходимости проверять результат работы malloc.

Задолго до того, как malloc потерпит неудачу, операционная система уже столкнулась с множеством проблем.

+3

Ваш ответ - несвязанный наряд. Я удалил половину. Также ваш ответ плох, поэтому я проголосовал за него. – kay

+0

Я не знаю, почему этот сайт позволяет редактировать мой пост. Но с OOM-Killer и Overcommit памяти проверьте нулевой указатель после того, как malloc больше не нужен и станет вводящим в заблуждение. – Shaoquan

+0

См. Http://stackoverflow.com/faq#editing.Вы тоже можете отменить мои изменения ... К оригинальному вопросу: это правда, что современные ОС распределяют RAM для процесса лениво и overcommit. И когда доступ к памяти будет фактически получен, она будет выделена. И, возможно, кто-то должен немедленно получить OOM'd. Но это не вопрос. malloc называет brk, чтобы увеличить свою кучу с нетерпением. OS меня отрицает запрос. В этом случае malloc вернет NULL. Например. ulimit может ограничить максимальный размер виртуальной памяти рассматриваемого процесса. – kay