Как избежать сборки "мусора" в режиме реального времени приложение.NET?

Вот что мы придумали для копирования одного поля в другое для ~ 150_000 записей. Это заняло около 6 минут, но все еще значительно менее ресурсоемким, чем это было бы для создания экземпляра и повторения одного и того же количества объектов ruby.

js_query = %({
  $or : [
    {
      'settings.mobile_notifications' : { $exists : false },
      'settings.mobile_admin_notifications' : { $exists : false }
    }
  ]
})

js_for_each = %(function(user) {
  if (!user.settings.hasOwnProperty('mobile_notifications')) {
    user.settings.mobile_notifications = user.settings.email_notifications;
  }
  if (!user.settings.hasOwnProperty('mobile_admin_notifications')) {
    user.settings.mobile_admin_notifications = user.settings.email_admin_notifications;
  }
  db.users.save(user);
})

js = "db.users.find(#{js_query}).forEach(#{js_for_each});"
Mongoid::Sessions.default.command('$eval' => js)
11
задан miguel 24 January 2013 в 14:14
поделиться

13 ответов

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

Но если Вы знаете, что будете иметь занятым по сравнению с легкими периодами загрузки для Вашего приложения, Вы могли бы попробовать более общий GC.Collect () при достижении легкого периода для поощрения очистки перед следующим напряженным периодом.

20
ответ дан 3 December 2019 в 00:38
поделиться

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

0
ответ дан 3 December 2019 в 00:38
поделиться

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

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

Вы, скорее всего, захотите к "ленивой загрузке" свое объединение с экземплярами, таким образом, Ваш код масштабируется легко. Поэтому Ваш класс пула должен будет обнаружить, когда пустой экземпляр вытянут и заполнит его перед раздачей его. Затем, когда код вызова откладывает его в пуле, это - реальный экземпляр.

** "Пулинг объектов является шаблоном для использования, который позволяет объектам быть снова использованными, а не выделенными и освобожденными, который помогает предотвратить фрагментацию "кучи", а также дорогостоящие уплотнения GC".

http://geekswithblogs.net/robp/archive/2008/08/07/speedy-c-part-2-optimizing-memory-allocations---pooling-and.aspx

1
ответ дан 3 December 2019 в 00:38
поделиться

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

1
ответ дан 3 December 2019 в 00:38
поделиться

Насколько интенсивный приложение? Я записал приложение, которое получает 3 звуковых карты (Управляемый DirectX, 44.1 кГц, Стерео, 16-разрядный), в блоках 8 КБ, и отправляет 2 из этих 3 потоков к другому компьютеру через TCP/IP. UI представляет метр уровня звука и (гладкий) заголовок/художника прокрутки для каждого из этих 3 каналов. Это работает на ПК с XP, 1.8 ГГц, 512 МБ, и т.д. Приложение использует приблизительно 5% ЦП.

Я избежал ручного вызова методов GC. Но я действительно должен был настроить несколько вещей, которые были расточительны. Я использовал профилировщика Муравья RedGate для затачивания в на расточительных частях. Потрясающий инструмент!

Я хотел использовать пул предварительно выделенных массивов байтов, но управляемый блок DX выделяет буферы байта внутренне, затем возвращает это Приложению. Оказалось, что я не имел к.

3
ответ дан 3 December 2019 в 00:38
поделиться

Если это абсолютно строго ограничено во времени затем, необходимо использовать детерминированную платформу как C/C++. Даже вызов GC.Collect () генерирует циклы ЦП.

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

2
ответ дан 3 December 2019 в 00:38
поделиться

От звука его кажется, что Вы говорите о детерминированном завершении (деструкторы в C++), который не существует в C#. Самой близкой вещью, которую Вы найдете в C#, является Доступный шаблон. В основном Вы реализуете интерфейс IDisposable.

Основной шаблон - это:

public class MyClass: IDisposable
{
    private bool _disposed;

    public void Dispose()
    {
        Dispose( true );
        GC.SuppressFinalize( this );
    }

    protected virtual void Dispose( bool disposing )
    {
        if( _disposed )    
            return;

        if( disposing )
        {
            // Dispose managed resources here
        }

        _disposed = true;
    }
}
2
ответ дан 3 December 2019 в 00:38
поделиться

"Цель быть для предотвращения сборки "мусора" для использования любого ЦП во время строго ограниченного во времени процесса"

Q: Если строго ограниченным во времени, Вы подразумеваете слушание некоторой тайной части аппаратных средств, и Вы не можете позволить себе пропустить прерывание?

A: Раз так затем C# не является языком для использования, Вы хотите Ассемблер, C или C++ для этого.

Q: Если строго ограниченным во времени, Вы имеете в виду, в то время как существует много сообщений в канале, и Вы не хотите позволять Сборщику "мусора" замедлить вещи?

A: Раз так Вы волнуетесь напрасно. Звуками вещей Ваши объекты являются очень недолгими, это означает, что сборщик "мусора" переработает их очень эффективно без любой очевидной задержки в производительности.

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

5
ответ дан 3 December 2019 в 00:38
поделиться

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

Таким образом, Вы избегаете не только сборки "мусора", но и регулярной стоимости выделения также.

Наконец, действительно ли Вы уверены, что GC вызывает Вас проблема? Необходимо, вероятно, измерить и доказать это прежде, чем реализовать любые сохраняющие перфект решения - можно вызывать себя ненужная работа!

6
ответ дан 3 December 2019 в 00:38
поделиться

Вы совершаете нападки в себе - используют пул объектов и снова используют те объекты. Семантика вызовов тем возражает, должен был бы быть скрыт позади фасада фабрики. Необходимо будет вырастить пул некоторым предопределенным способом. Возможно, удвойте размер каждый раз, он поражает предел - алгоритм паводка или фиксированный процент. Я действительно настоятельно рекомендовал бы Вам не называть GC.Collect ().

Когда нагрузка на Ваше объединение понижается достаточно, Вы могли уменьшить пул, и это в конечном счете инициирует сборку "мусора" - позволяют CLR волноваться об этом.

11
ответ дан 3 December 2019 в 00:38
поделиться

Послушайте: http://msdn.microsoft.com/en-us/library/bb384202.aspx

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

18
ответ дан 3 December 2019 в 00:38
поделиться

Наденьте хорошее понимание и чувствуйте, как Сборщик "мусора" ведет себя, и Вы поймете, почему то, о чем Вы думаете здесь, не рекомендуется. если Вам действительно не нравится, когда CLR тратит объекты реконструкции времени в памяти много.

3
ответ дан 3 December 2019 в 00:38
поделиться

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

В случае Вы упоминаете, Вы звучите, как будто Вы генерируете много недолгих объектов - они приведут к наборам Gen0. Они происходят относительно часто так или иначе и являются самыми эффективными. Вы могли избежать их при наличии допускающего повторное использование пула объектов, если Вы предпочитаете, но лучше устанавливать наверняка, если GC является проблемой производительности прежде, чем принять такие меры - профилировщик CLR является инструментом для того, чтобы сделать это.

Нужно отметить, что сборщик "мусора" отличается на различных платформах.NET - на компактной платформе (который работает на Xbox 360 и на мобильных платформах), это - GC непоколений и как таковой, необходимо быть намного более осторожными, о каком мусоре программа генерирует.

7
ответ дан 3 December 2019 в 00:38
поделиться
Другие вопросы по тегам:

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