Выделение памяти / Узкое место Освобождения?

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

46
задан EmeryBerger 23 September 2015 в 17:07
поделиться

12 ответов

Это значительно, тем более, что фрагментация растет, и средство выделения должно искать тяжелее через большую "кучу" для непрерывных регионов, которые Вы запрашиваете. Большинство чувствительных к производительности приложений обычно пишет свои собственные средства выделения блока фиксированного размера (например, они просят у ОС память 16 МБ за один раз и затем распределяют его в фиксированных блоках 4 КБ, 16 КБ, и т.д.) избегать этой проблемы.

В играх я видел, что вызовы к malloc () / свободный () используют целых 15% ЦП (в плохо записанных продуктах), или с тщательно записанными и оптимизированными средствами выделения блока, всего 5%. Учитывая, что игра должна иметь последовательную пропускную способность шестидесяти герц, имение ее останавливается для 500 мс, в то время как сборщик "мусора" работает, иногда не практично.

37
ответ дан Crashworks 26 November 2019 в 20:20
поделиться

Другие покрыли C/C++, таким образом, я просто добавлю немного информации о.NET.

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

существуют различные вещи, которые можно сделать для влияния на рабочую нагрузку сборщика "мусора" в.NET. Обычно, если у Вас есть большая память, ссылаются на сборщик "мусора", должен будет сделать больше работы. Например, путем реализации графика с помощью матрицы смежности вместо ссылок между узлами сборщик "мусора" должен будет проанализировать меньше ссылок.

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

1
ответ дан Brian Rasmussen 26 November 2019 в 20:20
поделиться

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

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

Это понятие также используется большинством приложений, которые имеют внимание на пропускную способность.

3
ответ дан Kosi2801 26 November 2019 в 20:20
поделиться

Согласно техническая спецификация MicroQuill SmartHeap, "типовое приложение [...] тратит 40% своего общего времени выполнения на руководящей памяти". Можно взять это число в качестве верхней границы, я лично чувствую, что типовое приложение тратит больше как 10-15% памяти выделения/освобождения времени выполнения. Это редко - узкое место в однопоточном приложении.

В многопоточных средствах выделения стандарта приложений C/C++ становятся проблемой из-за конкуренции за блокировку. Это - то, где Вы начинаете искать больше масштабируемых решений. Но имейте в виду Закон .

Amdahl
2
ответ дан Constantin 26 November 2019 в 20:20
поделиться

В Java (и потенциально другие языки с достойной реализацией GC) выделение объекта является очень дешевым. В JVM солнца только требуется 10 Циклов ЦП. malloc в C/c ++ является намного более дорогим, просто потому что это должно сделать больше работы.

все еще даже объекты выделения в Java являются очень дешевыми, делая, таким образом, для большого количества пользователей веб-приложения параллельно может все еще привести к проблемам производительности, потому что будет инициировано больше выполнений Сборщика "мусора". Поэтому существуют те косвенные затраты на выделение в Java, вызванном освобождением, сделанным GC. Этих затрат трудно определить количество, потому что они зависят очень от Вашей установки (сколько памяти делают Вы имеете), и Ваше приложение.

5
ответ дан HostileFork 26 November 2019 в 20:20
поделиться

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

class AClass
{
public:
  void *operator new (size_t size); // this will be called whenever there's a new AClass
   void *operator new [] (size_t size); // this will be called whenever there's a new AClass []
  void operator delete (void *memory); // if you define new, you really need to define delete as well
  void operator delete [] (void *memory);define delete as well
};

Многие шаблоны STL позволяют Вам определять пользовательские средства выделения также.

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

3
ответ дан Tim Cooper 26 November 2019 в 20:20
поделиться

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

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

В Java и основанных на JVM языках, new'ing объекты теперь очень, очень, очень быстро.

Вот одна достойная статья парня, который знает его материал с некоторыми ссылками в нижней части к большему количеству ссылок по теме: http://www.ibm.com/developerworks/java/library/j-jtp09275.html

8
ответ дан Alex Miller 26 November 2019 в 20:20
поделиться

Прежде всего, так как Вы сказали malloc, я предполагаю, что Вы говорите о C или C++.

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

А типичное обходное решение должно выделить как можно больше памяти впереди и держаться за него до Ваших выходов программы. Можно или использовать ту память, чтобы сохранить большие монолитные наборы данных или использовать реализацию пула памяти, чтобы скупо выдать его в блоках. Много реализаций библиотеки стандарта C/C++ делают определенное количество памяти, объединяющей себя по просто этой причине.

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

11
ответ дан MattK 26 November 2019 в 20:20
поделиться

Почти каждое высокопроизводительное приложение теперь должно использовать потоки для использования параллельного вычисления. Это - то, где уничтожитель скорости выделения реальной памяти входит при записи приложений C/C++.

В C или приложении C++, malloc/new должен взять блокировку на глобальной "куче" для каждой операции. Даже без состязательных блокировок совсем не свободны и должен избежаться как можно больше.

Java и C# лучше в этом, потому что поточная обработка была разработана в от запуска и работы средств выделения памяти от на пулы потоков. Это может быть сделано в C/C++ также, но это не автоматически.

21
ответ дан Zan Lynx 26 November 2019 в 20:20
поделиться

Практически все вы вне базы , если говорите о куче Microsoft. Синхронизация легко обрабатывается, как и фрагментация.

Текущая предпочтительная куча - это LFH, ( НИЗКАЯ ФРАГМЕНТАЦИЯ HEAP), она используется по умолчанию в операционных системах Vista + и может быть настроена в XP с помощью gflag, без особых проблем

Легко избежать проблем с блокировкой / блокировкой / конфликтом / пропускной способностью шины, а также с опцией

HEAP_NO_SERIALIZE

во время HeapAlloc или HeapCreate. Это позволит вам создавать / использовать кучу, не входя в блокированное ожидание.

Я бы рекомендовал создать несколько куч с помощью HeapCreate и определить макрос, возможно, mallocx (enum my_heaps_set, size_t);

будет хорошо, конечно, вам нужно перераспределить, бесплатно, чтобы настроить его соответствующим образом. Если хочешь пофантазировать, сделать free / realloc автоматически определять, какой дескриптор кучи сам по себе, оценивая адрес указателя или даже добавляя некоторую логику, позволяющую malloc определять, какую кучу использовать на основе его идентификатора потока, и построения иерархии куч для каждого потока и общие глобальные кучи / пулы.

API-интерфейсы Heap * вызываются изнутри с помощью malloc / new.

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

s вызываются внутри malloc / new.

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

s вызываются внутри malloc / new.

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

1
ответ дан 26 November 2019 в 20:20
поделиться

Я знаю, что отвечал ранее, однако это был ответ на другой ответ, а не на ваш вопрос.

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

Для меня это означает, что вы должны смотреть почти исключительно на NUMA осведомленные распределители .

Ни одна из предыдущих ссылок; Документ IBM JVM, Microquill C, SUN JVM. Покройте этот момент, поэтому я очень подозреваю их применение сегодня, где, по крайней мере, на AMD ABI, NUMA является выдающимся управляющим процессором памяти.

Руки вниз; реальный мир, фальшивый мир, любой мир ... Технологии запроса / использования памяти с поддержкой NUMA работают быстрее. К сожалению, в настоящее время я использую Windows и не нашел "numastat" который доступен в Linux.

Мой друг подробно написал об этом в своей имплементации ядра FreeBSD.

Несмотря на то, что я могу показать произвольно, обычно ОЧЕНЬ большие количество запросов к памяти локального узла поверх удаленного узла (подчеркивая очевидное преимущество производительности , пропускной способности ), вы можете угрюмо протестировать себя, и это, вероятно, именно то, что вам нужно сделать, поскольку ваша характеристика производительности будет очень специфичен.

Я действительно знаю, что во многих отношениях, по крайней мере, более ранняя версия 5.x VMWARE показала себя довольно плохо, по крайней мере в то время, из-за того, что не использовала преимущества NUMA, часто запрашивающие страницы с удаленного узла. Тем не менее, виртуальные машины являются уникальным зверем, когда речь идет о разделении памяти или контейнеризации.

Одна из ссылок, которые я процитировал, относится к внедрению Microsoft API для AMD ABI, который имеет специализированные интерфейсы выделения NUMA для разработчиков пользовательских приложений;)

Вот сравнительно недавний анализ , визуальный и все, от некоторых разработчиков надстроек браузера, которые сравнивают 4 различных внедрения кучи. Естественно, тот, который они разработали , оказывается на первом месте (странно, как люди, проводящие тестирование, часто показывают самые высокие баллы).

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

3
ответ дан 26 November 2019 в 20:20
поделиться

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

Эта статья была написана в 2005 году, и управление памятью в стиле JVM уже было впереди. С тех пор ситуация только улучшилась.

Какой язык может похвастаться более высокой производительностью необработанного выделения памяти, язык Java или C / C ++? Ответ может вас удивить - выделение памяти в современных JVM намного быстрее, чем в наиболее эффективных реализациях malloc. Общий путь кода для new Object () в HotSpot 1.4.2 и более поздних версиях составляет примерно 10 машинных инструкций (данные предоставлены Sun; см. Ресурсы) , тогда как наиболее эффективные реализации malloc на C требуют в среднем от 60 до 100 инструкций на вызов (Detlefs, et. al .; см. Ресурсы). А производительность выделения не является тривиальным компонентом общей производительности - тесты показывают, что многие реальные программы на C и C ++ , такие как Perl и { {1}} Ghostscript, тратить от 20 до 30 процентов общего времени выполнения на malloc и бесплатно - гораздо больше, чем выделение памяти и сборка мусора накладные расходы работоспособного приложения Java .

4
ответ дан 26 November 2019 в 20:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: