2013-03-08 3 views
2

Справочная информация: У меня есть служба, целью которой является предоставление объектов запрашивающим - она ​​в основном получает сложные данные из базы данных и преобразует ее один раз (немного как представление по данным) для создания упрощенная запись. Затем он запрашивает запросы от других служб, предоставляя до 100 тыс. Записей (в зависимости от характера запроса) по требованию.Оптимизация сбора долговечных объектов

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

Способ кэширования данных в списке объектов, которые являются мешками для стандартных типов .Net. Эти объекты не имеют ссылок ни на что другое. Периодически запись будет изменяться, и кеш должен быть обновлен, что означает, что исходная запись должна быть расположена, выброшена и заменена.

Теперь запись в кеше будет находиться там в течение длительного времени и будет отмечена для коллекции Gen 2; в значительной степени все коллекции будут происходить в фазе Gen2, поскольку эти объекты висят на протяжении веков (по назначению).

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

Я хочу, чтобы иметь возможность удалить ссылку на объект в списке таким образом, чтобы он не запускал полную коллекцию Gen2 ... Я думал, что, возможно, есть способ маркировать его как Gen0 а затем де-ссылку на него, прежде чем заменять его, но я не думаю, что это возможно.

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

Вопрос: Может ли кто-нибудь предложить способ удаления ссылок на долгоживущие объекты в формате GC по-дружески или, возможно, еще один способ приблизиться к этой проблеме?

+3

У вас есть проблема с памятью/производительностью? – ken2k

+0

Да, он работает при использовании памяти. Ive получил его до 1 ГБ (пик) - но он много обрабатывает - может использовать до 70% процессора в пике при одновременном запросе/сериализации/обслуживании больших данных большому количеству клиентов. Вот почему я начал смотреть на производительность GC, чтобы увидеть, есть ли что-то, что я могу сделать, чтобы получить чистый объем обработки. Я знаю, что у меня также есть проблема с потоками, но не думаю, что я могу (или хочу - мне нужно дать руководству повод для перехода на 4.5!) Исправить это, пока я не смогу перейти на .net 4.5 и не использовать async/await для выпуска потоков. – Jay

+0

@ Заметим, что GC perf, вызванный этим, будет ограничен периодическими шипами (обычно довольно предсказуемыми/равномерно распределенными). Это не изменит производительность * между * коллекциями. Поэтому, если ваше приложение уже горячее: вы можете смотреть не на что-то. –

ответ

6

На это нет простого ответа. Если у вас много долгоживущих объектов, то полные коллекции действительно могут повредить, так как я discussed here. Поскольку картина говорит тысячу слов:

enter image description here

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

То, как мы уменьшили влияние этого, было: не имеют gazillion долгоживущих объектов. Мы сделали это, чтобы сменить классы на struct, что означало, что единственным объектом, содержащим их, был только объект . Нам повезло, что данные были простыми и не включали string s, которые, конечно же, были бы объектами. Мы также сделали некоторые сумасшедшие работы fixed-size buffer, чтобы уменьшить количество вещей, которые были ранее собраны, и изменили то, что было ссылок на индексы (в массив). Если вы сделать должны использовать string данные, возможно, пытаются убедиться, что вы не имеете 20,000 различныеstring instancs с тем же значением - какой-то ручной Interner (а Dictionary<string,string> хватило бы) может быть очень полезным там.

Обратите внимание, что это не должно повлиять на общественного API, так как вы всегда можете создать старые class данные из struct хранения - разница в том, что эта class будет существовать только на короткое время, как DTO - так будут собраны дешево в следующей развертке gen-0.

YMMV, но это сработало достаточно хорошо для нас.

Проблема в следующем: вы должны быть действительно осторожны при работе с struct s; Я настоятельно рекомендую сделать их неизменными.

+0

Спасибо за отличную статью и даю мне что-то новое, о чем можно подумать. – Jay

Смежные вопросы