Повышение производительности затрат памяти в многопоточном распределенном приложении - PullRequest
4 голосов
/ 22 февраля 2012

Мне удалось улучшить производительность веб-приложений, чтобы они были на 10% быстрее, чем раньше.При этом я заметил, что использование памяти удвоилось !!!

Тестовое приложение выполняет: вызывает веб-сервис, выполняет сложные бизнес-действия * [количество пользователей] * [количество раз]

Я проверяю свой код изменения, но ничто не вызывает подозрений в использовании большего количества памяти ... (все, что я сделал, это удалил строки кода, сериализовавшего DataSet, в байт [] и сохранил его в кеше). Я проверял снова и снова вмногопоточный тест:

  1. По мере того, как я пропускал все больше и больше кода ( производительность улучшена - память увеличилась )
  2. Когда я повторял плохой код в цикле (производительность былаплохая память вышла из строя)

Может ли кто-нибудь объяснить, почему ????

Код ниже:

До: (Время цикла: 100% Память 100%)

            outStream = new MemoryStream();
            new BinaryFormatter().Serialize(outStream, stateData); 
            outStream.Close();
            SessionSettings.StateData_Set(stateId, outStream.ToArray());
            outStream.Dispose();

После варианта 1: (Время цикла: 200% памяти 50%)

for (int i = 0; i < 20; i++)
            {
                outStream = new MemoryStream();
                new BinaryFormatter().Serialize(outStream, stateData); 
            }
            outStream.Close();
            SessionSettings.StateData_Set(stateId, outStream.ToArray());
            outStream.Dispose();

После варианта 2: (Время цикла: 90% памяти 200%)

                //outStream = new MemoryStream();
                //new BinaryFormatter().Serialize(outStream, stateData); 
            //outStream.Close();
            SessionSettings.StateData_Set(stateId, null);
            //outStream.Dispose();

SessionSettings.StateData_Set помещает объект в

dictionary<string,dictionary<string, object>>

, что означает

<Sessions<DataKey,DataObject>>

в конце oВ каждом цикле внутренний словарь удаляет запись, и в конце каждого пользовательского сеанса весь внутренний словарь удаляется из внешнего словаря.

Ответы [ 2 ]

4 голосов
/ 22 февраля 2012

Еще одно предположение: если ваше приложение выделяет слишком много памяти (возможно, путем частой сериализации), CLR будет запускать GC гораздо чаще. Наблюдая за счетчиком производительности -> Время в GC, вы заметите, что GC израсходует много ресурсов процессора - я видел сценарии, превышающие 40%. Это особенно верно, если ваши наборы данных велики и хранилище байтов [] заканчивается на LOH.

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

Чтобы найти более надежное объяснение, опубликуйте некоторые показатели производительности: до оптимизации и после оптимизации. Интересно было бы: общий размер кучи, время, проведенное в GC.

3 голосов
/ 22 февраля 2012

Поскольку вы не предоставили никакого кода и только краткое объяснение, это скорее загадка, чем вопрос.

Итак, возможно, к CACHED DATASET обращались 10 пользователей примерно в одно и то же время.CACHED DATASET был заблокирован и просмотрен пользователями СИНХРОННО (по одному за раз).Это будет работать плохо в многопоточном тесте, но потребует мало памяти.

Возможно, к REPLICATED DATASET (uncached) обращались 10 пользователей примерно в одно и то же время.У каждого пользователя будет своя собственная копия ЗАПИСАННОЙ БАЗЫ ДАННЫХ.Без блокировки / синхронизированного доступа и нескольких копий DATASET память увеличится, но производительность улучшится.

...