赏梅斋

关注微软技术

博客园 首页 新随笔 联系 订阅 管理
  90 Posts :: 2 Stories :: 171 Comments :: 32 Trackbacks

通过提出以下问题,可以确定是否可能存在错误释放的对象:

  1. 应用程序池是否频繁进行回收,尤其是在负载过重的情况下(假设应用程序池被设置为在达到内存阈值时进行回收)?

    内存阈值应该在 800 MB 到 1.5 GB 之间,假设 RAM 至少为 2 GB。如果将应用程序池回收设置为在较接近 1 GB 时发生,则效果最佳,但是请根据试验来确定最适合您的环境的设置。如果回收设置太低,则系统可能因应用程序池频繁进行回收而遇到性能问题。如果设置太高,则系统可能会因页面交换、内存碎片和其他问题而遇到性能问题。

  2. 系统性能是否低下,尤其是在负载过重的情况下?

    当内存使用量开始增加时,系统必须进行补偿,例如,通过对内存进行分页和处理内存碎片来进行补偿。

  3. 系统是否崩溃或者用户是否遇到意外错误,如超时或页面不可用错误,尤其是在负载过重的情况下?

    同样,当内存使用量增加或出现内存碎片时,某些功能会发生故障,因为这些功能无法为其他操作分配内存。在许多情况下,代码不会正确处理“内存不足”异常,从而导致虚假错误或误导错误。

  4. 系统是否使用自定义或第三方 Web 部件或自定义应用程序?

    您可能不知道这些 Web 部件必须释放 SharePoint 对象及其原因(假设垃圾收集自动执行此功能)。但并不是所有情况下都是这样。

如果您对第 4 个问题以及其他的一个或多个问题回答“是”,则自定义代码很可能未正确释放项目。

如果网站显示前面描述的任意异常行为,则通过检查 ULS 日志(可在 C:\Program Files\Common Files\microsoft shared\Web Server Extensions\14\LOGS 处获得)中是否有与 SPRequest 对象相关的条目,可以确定原因是否是由于错误释放对象而引起的内存泄露。SPSiteSPWeb 的每个实例都包含对 SPRequest 对象的引用,而该对象又包含对非托管的 COM 对象的引用,此非托管的 COM 对象处理与数据库服务器之间的通信。SharePoint Foundation 将监视每个特定线程和并行线程中存在的 SPRequest 对象的数目,并在以下三种情况下向日志中添加有用的条目:

  • SPRequest 对象的总数超出了可配置的阈值。

  • SPRequest 对象在线程结束后继续存在。

  • SPRequest 对象已通过垃圾收集从堆中移除

第一种情况最经常发生,尤其是网站使用默认阈值(八个 SPRequest 对象)时。每当 SPRequest 对象的数目超过此阈值时,ULS 日志中就会出现以下条目:

“可能有过量的 SPRequest 对象(对象数)当前在线程 线程号 上未得到释放。请确保正确释放此对象或其父项(如 SPWebSPSite 对象)。此对象的分配 ID 为:{GUID}”

最佳阈值因网站以及网站上运行的应用程序的性质而异。当网站遇到性能问题时,应该监视安装的 ULS 日志,以了解网站应用程序将创建多少个 SPRequest 对象。这有助于确定网站和应用程序的设计是否会创建太多的 SPRequest 对象。即使错误释放对象 是性能问题的原因,可能也需要重新设计网站或自定义网站应用程序,以减小 SPRequest 对象过量激增所消耗的内存总量。

由于太低的默认阈值可能不适用于许多网站,所以可以通过编辑以下注册表子项来更改此阈值:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings

LocalSPRequestWarnCount = 所需阈值

在确定错误释放对象可能会导致 SPRequest 对象激增并且会徒然增加网站占用的内存之后,可以通过查找以下两个条目来查找错误释放的特定实例。这两条消息均针对由于错误释放 SharePoint 对象而浪费内存的情况,并且都与单一线程上的 SPRequest 对象的数目和状态相关:

  • “在此线程结束之前未释放 SPRequest 对象。为了避免浪费系统资源,请在用完此对象或其父项(如 SPSite 或 SPWeb)之后立即将其释放。现在将释放此对象。分配 ID: {GUID}。要确定在哪里分配了此对象,请在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings 处创建注册表子项。然后在此项下面创建名为 SPRequestStackTrace 且值为 1 的新 DWORD。”

    此消息表明 SPRequest 对象由于在线程结束后仍然存在而被释放。

  • “SPRequest 对象已被垃圾收集器回收,而不是被明确释放。为了避免浪费系统资源,请在用完此对象或其父项(如 SPSite 或 SPWeb)之后立即将其释放。分配 ID: {GUID}。要确定在哪里分配了此对象,请在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings 处创建注册表项。然后在此项下面创建名为 SPRequestStackTrace 且值为 1 的新 DWORD。”

    此消息表明垃圾收集器释放了 SPRequest 对象。

为了找出引起问题的代码,可以在日志中搜索包含分配标识符的条目,或者按照警告中的说明进行操作并向注册表中添加以下子项设置:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings SPRequestStackTrace = 1

此子项设置可确保在出现这些警告时向日志中添加原始 SPRequest 分配(每当创建 SPSiteSPWeb 对象时就会发生)的堆栈跟踪。

 

 

posted on 2011-02-11 17:42 赏梅斋 阅读(...) 评论(...) 编辑 收藏