【问题标题】:Implement object-caching in classic ASP memory-leaking在经典的 ASP 内存泄漏中实现对象缓存
【发布时间】:2009-08-10 16:52:15
【问题描述】:

我尝试在经典 ASP 站点中实现不同的缓存实现,以便在流量大时卸载数据库。

我的做法是这样的:

在 global.asa 中创建一个全局 HashTable 对象,我稍后会在其中存储 jscript 对象

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

这给了我一个全局哈希表对象,我在某些时间间隔替换哈希表的内容。大小只会略有不同,但我每次都会 .Remove() 和 .Add() 所有对象。

这很好用,除了在一定时间后,应用程序的内存分配变得很高,导致会话的不合理行为。它将“忘记”会话,但不会调用 global.asa 中的 OnSessionStart()。因此,给访问者留下一个空的 Session-collection。

我能以某种方式改进内存重新分配过程吗?有没有更好的对象缓存方法?

我尝试过使用带有 json 序列化数据的纯文本文件,但是反序列化的开销很大。我考虑过二进制序列化,但我不确定它在经典 ASP 中是否可行。

【问题讨论】:

    标签: optimization caching asp-classic memory-leaks


    【解决方案1】:

    在常规“Scripting.Dictionary”上使用 .NET HashTable 的原因是什么?

    当你做经典的 ASP 时,为什么普通的 COM 对象还不够?

    【讨论】:

    • afaik Scripting.Dictionary 和 IISSample.LookupTable 都绑定到它们只能存储原始数据类型(字符串和数字)的事实。那会让我再次需要序列化。当然,我不需要反序列化所有内容。 LookupTable 也不支持动态更改(我知道 Scripting.Dictionary 存在问题,但我不能肯定)
    • Scripting.Dictionary 可以存储您喜欢的任何值。对象引用原始值。唯一的限制:键必须是字符串。
    • 另请注意,链接的 MS 知识库文章“Scripting.Dictionary Object Fails in ASP Application Scope”根本不适用于您。
    • 我可以将它存储在应用程序中吗?我去看看。
    【解决方案2】:

    不要试图重新发明轮子。使用内存缓存。它是免费且易于设置的。作为奖励,有 ttl(生存时间)并且可以在服务器边界之外工作

    【讨论】:

    • 据我所知,memcached 至少需要 2 个单独的服务器。对于像这样的简单任务来说,这是一个相当大的设置。它也是基于网络的,这意味着比将其存储在 RAM 中的开销更大。当然,正如你所说,更具可扩展性,如果我创建 1 个设置,我可以将它用于多个站点,但我不确定我是否在不久的将来有这种需求,甚至从长远来看也没有。
    • memcache 可以在同一台机器上运行。你是对的,有一点开销。但与不必每次都进行查询相比,这是微不足道的。
    【解决方案3】:

    这只是一个猜测,但可能是因为您将 JScript 对象存储到 .net 哈希中,您仍然可以保留对该对象的引用,因此垃圾收集永远没有机会正确完成其工作。

    我之前使用过带有 JSON 字符串的应用程序,在重新水合数据时可以快速缓解和评估。

    如果您担心您的数据会过时,您可以使用 XMLHTTPRequest 服务器端(速度快得惊人)来调用 aspx 页面,该页面将为您进行搜索并返回 JSON 字符串。 aspx 页面可以使用 .net 出色的缓存为您处理缓存,甚至可以使用 SharpZipLib 压缩 JSON 字符串,然后将其存储在缓存中,以进一步减少内存占用。这也是在缓存中存储 XML 文件的好方法(600K 到 25K 在 0.0016 秒内!)

    我们之前在项目中使用过以上所有方法,虽然并不完美,但基于当时的限制和遗留代码,这是一个足够好的解决方案。而且它们都非常非常快(不是按照 .net 标准,而是为了真正快速编写脚本)。

    【讨论】:

    • 好吧,我们在尝试将 json 字符串存储在 Application 中时遇到了同样的内存问题。尽管 eval 非常快,但它在 CPU 上的强度也非常高。我们在 SessionStart 中也遇到了这种奇怪的行为。在那种情况下,这一切都取决于我们存储在应用程序中的数据量,所以它似乎不是万无一失的,或者我们做错了什么。当 w3wp.exe 开始用完大约 300MB 时,我们开始为一些访问者遇到这个间歇性问题。
    • CPU 密集型是可以的,如果它只是这里和那里的奇怪峰值,那么是的,你做了太多的工作,你将不得不重新审视这个解决方案。可能是您试图对缓存做太多事情。您真的需要缓存所有内容吗?如果你这样做了,那么你可能不得不去构建自定义函数来从应用程序重建你的对象,而不是评估它们(参见stackoverflow.com/questions/1196525/…)。我知道你说过你不想这样做,但现在你的选择有限
    【解决方案4】:

    我会选择一种技术含量更低的方法,并将每个对象分别(使用字符串键)存储在 Application 对象中。这样,从脚本引擎的角度来看,您不仅拥有一个巨大的对象。你认为这会有所帮助吗?

    【讨论】:

    • 试过了,弄乱应用程序并不是一个好主意。从应用程序写入/读取数据往往会耗尽所有内存和会话垃圾问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2012-10-31
    • 1970-01-01
    相关资源
    最近更新 更多