【问题标题】:Processes launched by a service can't allocate memory服务启动的进程无法分配内存
【发布时间】:2011-12-26 08:05:54
【问题描述】:

我有一个 C# 服务作为 LocalSystem 帐户运行,它根据需要启动许多其他进程。这几个月来一直很好。就在本周,一些子流程正在崩溃。我为它们附加了一个远程调试器,它们在内存分配中失败(C++ new 运算符返回 0x0),这是导致崩溃的间接原因。

有趣的是,如果我将 RDP 导入机器,我可以轻松地从 CMD 启动进程,没有任何问题。然而,当服务启动它时,就不行了。

机器运行的是 Windows XP SP3。它不超出提交费用大约是物理 RAM 的 80%。

对于服务可以使用多少进程或多少内存(包括由该服务生成的进程)是否有一些特殊限制??

这些进程无法分配内存的任何其他想法。

编辑:

我已经很好地查看了来自 SysInternals 的 Procmon 崩溃场景,但它没有显示任何内容(我可以看到)。一切看起来都很正常,然后突然崩溃。我可以通过附加远程调试器确认它在从 c++ 新调用取消引用空指针后崩溃。这是应用程序中分配的首批对象之一,它永远不会失败。

我还发现,如果我启用服务选项:允许服务与桌面交互,那么所有子进程都会正确启动。但是,当您通过 RDP 连接时,do 会出现在桌面上,如果您通过 RDP = YUK 注销,则会不幸终止!不过,这仍然不是一个理想的解决方案 - 我真的很想知道为什么子进程在第 6 个子进程之后无法分配内存。

【问题讨论】:

  • 请在帖子中添加来自这些崩溃的事件查看器中的错误消息。
  • 事件日志中的唯一消息是来自调试器未能加载然后应用程序崩溃(读取无法访问的地址):“MDS_16.exe [456] 中发生未处理的 win32 异常。Just-In -时间调试此异常失败,出现以下错误:调试器无法启动,因为没有用户登录。请查看文档索引以获取“即时调试,错误”以获取更多信息。有关更多信息,请参阅帮助和支持以go.microsoft.com/fwlink/events.asp为中心。”
  • 正如我之前提到的,我可以远程调试崩溃的进程,并且有一个 C++ 新调用返回 null,它正在被取消引用,从而兑现崩溃。真正的问题是进程无法分配内存来启动。
  • 我了解这些进程即使在运行服务时也具有图形界面。所以最好检查它们的内核对象使用情况。在任务管理器,进程选项卡,菜单查看/选择...中,添加工作集(内存)&句柄&线程&用户对象&GDI对象。寻找稳定递增的计数器,尤其是在发生崩溃时,因为它们有一个上限。
  • 您实现了自己的operator new,还是使用了CRT提供的operator new

标签: windows windows-xp memory service


【解决方案1】:

对于服务可以使用多少进程或多少内存(包括由该服务生成的进程)是否有一些特殊限制??

作业对象可用于限制进程(或进程组)的内存使用,但需要将相关进程与该作业对象相关联。

服务进程没有这样的作业对象。

考虑使用注册表允许您从受影响进程的启动开始调试:http://msdn.microsoft.com/en-us/library/a329t4ed.aspx

【讨论】:

  • 因为这是一台远程机器,将环境设置为使用JIT自动调试是行不通的。此外,这些进程作为 LocalSystem 使用运行,JIT 调试器无法启动,因为用户没有控制台。我已经设法将远程调试器附加到应用程序,并且可以看到它无法使用返回 NULL 的 c++ new 运算符分配内存。因此,关于内存限制的问题可能是造成这种情况的原因......
【解决方案2】:

您可能会发现 SysInterals Procmon 对于查看您的流程正在发生的事情很有用。

【讨论】:

  • 我在进程崩溃时仔细查看了 Procmon。我没有看到任何指向它为什么无法分配内存的东西。有一堆 DLL 加载和注册表查询。然后它开始加载 jit 调试器——这是为了响应从失败的内存分配中取消引用空指针而导致的崩溃。 :(
【解决方案3】:

我希望这个答案能在未来对某人有所帮助...... 我遇到了同样的问题 - 如果允许渲染窗口,应用程序会运行良好,但如果在服务下运行并且不允许与桌面交互,则会在启动时崩溃。解决方案在于增加注册表中非交互式windows站堆的大小,在我的机器上设置为512KB,而交互式windows站堆为3072KB。

你可以去改变它

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows

该值是一个长字符串。您需要更改 SharedSection 设置,如下所示:

SharedSection=1024,3072,512

第二个数字是 interactive windows station heap 的大小,最后一个是 non-interactive windows station heap 的大小。如果删除最后一个数字,则交互式和非交互式 Windows 站堆将具有相同的大小。我就是这么做的。

在此处阅读详细信息:http://support.microsoft.com/kb/184802

【讨论】:

  • 我遇到问题的机器现在已经死了。我们通过在另一个已经运行的服务中包含该功能来解决这个问题。但是,我会给你这个怀疑的好处!
猜你喜欢
  • 2012-03-05
  • 2015-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多