在经典ASP中,我什么时候需要将对象设置为“nothing”?

7
一方面,建议始终关闭对象是如此普遍,以至于如果忽略它,我会感到愚蠢(例如VBScript Out Of Memory Error)。
然而,忽略Eric Lippert的智慧同样愚蠢,他似乎持不同意见:http://blogs.msdn.com/b/ericlippert/archive/2004/04/28/when-are-you-required-to-set-objects-to-nothing.aspx 我已经努力修复了许多经典ASP中出现OOM错误的Web应用程序。我的第一个(费时的)任务总是搜索未关闭的对象和未设置为Nothing的对象的代码。
但是我从来没有百分之百地相信这有所帮助。(也就是说,我发现很难准确地确定什么是有帮助的……)
3个回答

5
这篇文章由Eric撰写,讨论的是独立的VBScript文件,而不是使用VBScript编写的经典ASP。请看评论,然后是Eric自己的评论:
“关于ASP - 很好的观点,这是我没有考虑过的。在ASP中,有时很难知道你在哪里以及你所处的作用域。”
因此,从这个观点来看,他所写的一切都与经典ASP无关,即您应该始终将所有内容设置为Nothing。
至于内存问题,我认为将对象(或数组)分配给Session或Application等全局范围是造成此类问题的主要原因。这是我首先要寻找并重新编写的内容,仅在Session中保留单个标识符,然后使用数据库来管理数据。

你认为大部分经典 ASP 是用哪种语言编写的? - Damien_The_Unbeliever
@Damien_The_Unbeliever 这不相关,Eric 正在谈论独立的 VBScript 文件。我会在帖子中更清楚地表述。 - Shadow The Spring Wizard
他在谈论引擎。就像你自己引用的那样,“有时候很难确定你所处的范围”。这并不意味着说“当你退出 ASP 的一个范围时,上面说的是不正确的”。 - Damien_The_Unbeliever
好的,谢谢,那将是我下次检查的首要事项之一。为什么在ASP中使用VBScript和独立的VB之间的建议会有所不同呢?我确实再次阅读了EL文章,但并没有真正理解它。 - Martin Hansen Lennox
1
@MartinHansenLennox - 如果我没记错的话,有些作用域发生了变化。此外(我认为更重要的是),当300多人访问页面时,对象在服务器上占用内存要容易得多,而不是一个人在他们的桌面上运行脚本。 - AnonJr

2
基本上,通过将一个COM对象设置为Nothing,您强制其终止运行确定性,这给了您处理它可能引发的任何错误的机会。
如果您不这样做,您可能会遇到以下情况:
- 您的代码引发了一个错误 - 错误没有在您的代码中处理,因此... - 在您的代码中实例化的其他对象超出范围,它们的终止程序运行 - 其中一个终止程序引发了一个错误 - 传播的错误是终止程序超出范围引发的错误,掩盖了原始错误。
我记得从遥远的过去那里得知特别建议关闭ADO对象。我不确定这是因为ADO对象中存在漏洞,还是仅仅是为了上述原因(这适用于任何可以在其终止程序中引发错误的对象)。
这个建议经常被重复提出,但往往没有可信的理由。(“虽然ASP应该自动关闭和释放所有对象实例,但显式关闭和释放对象引用总是一个好主意”)。

是的,这是我一遍又一遍读到的建议。除了 ASP 垃圾回收器不总是正常工作的解释之外,没有其他解释。也许我应该接受这个简单的解释...但我很好奇 :) - Martin Hansen Lennox
@MartinHansenLennox。在 ASP classic 中没有垃圾回收器。 - Joe
@Joe Classic ASP 有垃圾回收机制。在 IIS 5 发布时,它得到了相当大的改进。 - AnonJr

1
值得注意的是,在这篇文章中,他并不是说你永远不用担心将对象设置为nothing——只是每个脚本中每个对象都应该遵循这种默认行为。
虽然我怀疑他有些过于快速地否决了“我在其他地方看到过”的编程行为方法,但我愿意打赌,有一个原因让Eric没有考虑到这一点,导致它被传递为硬性规定——处理初级程序员。
当你开始更仔细地看Dreyfus模型的技能习得时,你会发现在习得新技能的初级阶段,学习者需要简单易懂的步骤。他们还没有足够的知识或能力来做出Eric后来推荐的判断。
回想一下你开始编程的时候。你能轻松判断是否“将[昂贵的]对象设置为Nothing,如果你已经完成它们,并且在超出范围之前完成了它们”吗?你真的知道哪些对象是昂贵的,或者它们何时真正超出范围吗?
因此,大多数入门级程序员被告知“在使用完每个对象后始终将其设置为 Nothing”,因为他们可以理解和遵循。不幸的是,很少有程序员花时间自我教育、学习并成长到更高级别的 Dreyfus 阶段,在那里你可以使用更微妙的情境方法。
然后我们回到我之前的陈述——即使我们中最好的人也从早期阶段开始,我们本能地关闭所有对象,因为那是我们所能做到的最好的。我们留下了大量的代码,现在人们查看它,将我们当前的能力向后投射到早期的工作中,并假定我们出于我们不理解的原因而这样做。
我得走了,但我希望稍后再展开这个话题...

这对我来说似乎很合理。但在我看来,即使是经验丰富的开发人员也经常提出这样的建议。也许这是上面提到的 asp / 独立 vb 问题。 - Martin Hansen Lennox
@MartinHansenLennox 这很大程度上取决于你所说的“资深”。我认识有10年经验的开发人员,也认识一年经验重复了10年的开发人员。 - AnonJr
我应该给自己加个注释:我应该更详细地阐述缺乏成长的问题,以及那些不够谦虚的开发者可能会向那些他们认为“低人一等”的人传授真理——这在某种程度上导致对每个人都像是处于开发的初学阶段。 - AnonJr
非常正确。我永远不会停止学习,了解自己还有多少不知道的东西 - 或者类似这样的话。 - Martin Hansen Lennox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接