Реализация объектного кэширования в классическом ASP с утечкой памяти

Я попытался реализовать различные реализации кеширования на классическом сайте ASP, чтобы разгрузить базу данных во время интенсивного трафика.

Мой подход был таким:

Создайте глобальный объект HashTable в global.asa, где я позже сохраню jscript-объекты внутри

<object id="SIZE_LIST" progid="System.Collections.HashTable" runat="Server" scope="Application"></object>

Это дает мне глобальный объект HashTable, который я через определенные промежутки времени заменяю содержимым HashTable. Размер будет незначительно отличаться, но я, тем не менее, каждый раз использую .Remove () и .Add () для всех объектов.

Это работает очень хорошо, кроме того, что по прошествии определенного времени объем памяти приложения становится слишком высоким, что приводит к иррациональному поведению сеансов. Он «забудет» сеансы, но не вызовет OnSessionStart () в global.asa. Таким образом, оставляя посетителей с пустой Session-коллекцией.

Могу ли я как-нибудь улучшить процесс перераспределения памяти? Есть ли лучший подход для кеширования объектов?

Я пробовал использовать простые текстовые файлы с json-сериализованными данными, но десериализация этого требует значительных накладных расходов. Я думал о двоичной сериализации, но не уверен, возможно ли это вообще в классическом ASP.


person jishi    schedule 10.08.2009    source источник


Ответы (4)


Каковы причины использования .NET HashTable вместо обычного Scripting.Dictionary?

Когда вы работаете с классическим ASP, почему обычного COM-объекта недостаточно?

person Tomalak    schedule 10.08.2009
comment
afaik как Scripting.Dictionary, так и IISSample.LookupTable привязаны к тому факту, что они могут хранить только примитивные типы данных (строки и числа). Это снова оставило бы мне потребность в сериализации. конечно, мне не нужно было бы все десериализовать. LookupTable также не поддерживает динамические изменения (и я знаю, что у нас были проблемы с Scripting.Dictionary, но я не могу сказать наверняка) - person jishi; 11.08.2009
comment
Думаю, проблема заключалась в следующем: 4guysfromrolla.com/aspfaqs/ShowFAQ.asp?FAQID = 129 - person jishi; 11.08.2009
comment
Scripting.Dictionary может хранить любое значение, которое вам нравится. Объект ссылается на примитивные значения и. Единственное ограничение: ключи должны быть строками. - person Tomalak; 11.08.2009
comment
Также обратите внимание, что связанная статья MS KB Scripting.Dictionary Object Fails в области приложения ASP к вам не относится. - person Tomalak; 11.08.2009
comment
И я могу его хранить в Приложении? Я проверю это. - person jishi; 11.08.2009
comment
Конечно. Пока вы проверяете наличие проблем с потоками и тщательно вызываете Application.Lock для защиты доступа для записи, это не должно быть проблемой. - person Tomalak; 11.08.2009

не пытайтесь изобретать велосипед. Используйте memcache. Это бесплатно и легко установить. В качестве бонуса имеет ttl (время жизни) и работает за пределами сервера

person Toad    schedule 10.08.2009
comment
Из того, что я узнал, для memcached требуется как минимум 2 отдельных сервера. Это довольно большая установка для такой простой задачи. Он также является сетевым, что означает больше накладных расходов, чем его хранение в ОЗУ. Конечно, как вы говорите, он гораздо более масштабируемый, и если я создам одну настройку, я могу использовать ее для нескольких сайтов, но я не уверен, понадобится ли мне в ближайшем будущем, даже в долгосрочной перспективе. - person jishi; 11.08.2009
comment
memcache может работать на той же машине. Вы правы, это немного накладные расходы. Но это мало по сравнению с тем, что вам не нужно каждый раз повторять запросы. - person Toad; 11.08.2009

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

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

Если вы беспокоитесь о том, что ваши данные устарели, вы можете использовать серверную часть XMLHTTPRequest (что на удивление быстро) для вызова страницы aspx, которая выполнит поиск и вернет вам строку JSON. Страница aspx может обрабатывать кеширование за вас с помощью фантастического кеширования .net и может даже заархивировать строку JSON с помощью SharpZipLib перед тем, как спрятать ее в кеш, чтобы еще больше уменьшить объем памяти. Это также отличный трюк для хранения файлов XML в кеше (с 600 КБ до 25 КБ за 0,0016 секунды!)

Мы использовали все вышеперечисленное в проектах раньше, не идеальное, но достаточно хорошее решение, основанное на ограничениях и устаревшем коде того времени. И все они очень-очень быстрые (хорошо, не по стандартам .net, но для сценариев это очень быстро).

person Pete Duncanson    schedule 11.08.2009
comment
Что ж, у нас была такая же проблема с памятью при попытке сохранить json-строки в Application. Несмотря на то, что eval выполняется довольно быстро, он также довольно сильно нагружает процессор. И у нас также было такое странное поведение с SessionStart. В этом случае все зависело от количества данных, которые мы храним в приложении, поэтому это не кажется надежным, или мы делаем что-то не так. Когда w3wp.exe начинает использовать около 300 МБ, у некоторых посетителей появляется эта периодически возникающая проблема. - person jishi; 11.08.2009
comment
Интенсивная нагрузка на ЦП - это нормально, если это просто странные всплески здесь и там - нет, тогда да, вы делаете слишком много работы, и вам придется пересмотреть это решение. Возможно, вы слишком много делаете со своим кешированием. Вам действительно нужно все кешировать? Если вы это сделаете, вам, возможно, придется пойти по пути создания пользовательских функций для перестройки ваших объектов из приложения вместо их исключения (см. stackoverflow.com/questions/1196525/). Я знаю, вы сказали, что не хотите этого делать, но сейчас ваши возможности ограничены - person Pete Duncanson; 12.08.2009

Я бы выбрал менее технологичный подход и сохранял бы каждый объект отдельно (со строковыми ключами) в объекте Application. Таким образом, с точки зрения механизма сценариев, у вас не будет одного огромного объекта. Как вы думаете, это вообще поможет?

person mike nelson    schedule 21.12.2009
comment
попробовал, и возиться с приложением было не такой уж и хорошей идеей. Запись / чтение из приложения постоянно приводит к израсходованию всей памяти и проблемам с удалением сессий. - person jishi; 30.12.2009