内存不足时出现错误代码137 vs 1

时间:2015-06-19 17:51:34

标签: c# bash mono

上下文

我在linux bash中运行以下命令:

mono --debug --debugger-agent=transport=dt_socket,address=198.178.155.198:10000 ./Stress.exe

Stress.exe是一个C#应用程序。

会发生什么

在某一时刻,系统内存不足,这是需要的。返回错误代码。

返回错误代码(echo $?)

代码1:当我的程序因为内存不足而创建一个throw时。

代码137:当内存过载时被OS杀死。

问题

为什么有时候操作系统会杀死我的应用程序?为什么结果并不总是一样?

2 个答案:

答案 0 :(得分:3)

假设:

  • Mono正在运行基于SGEN的GC
  • Linux OOM杀手实际上已启用
  • 你的Stress.exe只是分配管理内存,即没有Native interop,没有使用Marshaling内存分配器,没有标记为不安全的代码等。
  • 您不断创建对象并且永远不会释放这些引用。

让我们谈谈SGEN,所以当你分配对象时,它们是在托儿所中创建的,因为你在托儿所用完了内存,当GC进行扫描并且必须进行托儿所收集,因为它已经满了,直播对象移动到它的主要堆。如果主头已满,则请求更多OS内存。您可以调整分配给单声道应用程序的初始内存量,甚至可以修复Sgen可以使用的内存量(最大值)。此外,超过8000字节的管理对象由Sgen的大对象空间管理器处理,这是非基于托儿所/主要堆的内存,但它仍然是托管对象/内存。

通常,当mono需要更多空间用于托管对象并且OS请求附加块并且操作系统显示NO时,您会看到OutOfMemory异常和0退出代码。你的压力测试很开心。

但是,OOM​​正在观察单声道进程,并将其得分(oom_score)调高得越来越高。它可以在任何时刻打击单声道进程,但我会把它在GC扫描时正确的几率,当应用程序线程被SGEN暂停但在SGEN实际执行操作系统内存请求之前由于管理不足nusery中的记忆空间。因此,你得到了137. 137& 127 = 9,因此单声道进程发送了一个SIGKILL信号(kill -9)并且你的压力测试不满意。

尝试将其作为实验:

  • 1)如果完全关闭OOM杀手。假设这不是一个 你正在强调的现场制作盒;-)你应该看到的 "的System.OutOfMemoryException" 100%的时间。
  • 或2)设置oom_adj 只有单声道进程到-17和OOM将不管它。只是 在shell脚本中包装单声道启动以获取它的pid和echo -17 到那个过程的oom_adj。
  • 或3)如果你将单声道处理的oom_adj调低到最低(一直到-16,你会看到单声道捕获它自己的管理内存中断'更多的时间&#39 ;但它永远不会100%的时间....

这不是Mono和/或Sgen / GC相关的问题'一点都不消耗越来越多内存的任何进程都将被OOM杀死。无论是一个胖胖的Oracle数据库,还是只有内存泄漏的app / daemon等等,它们都会被杀掉。

答案 1 :(得分:1)

“本文描述了Linux内存不足(OOM)杀手以及如何找出它杀死特定进程的原因。它还提供了配置OOM杀手的方法,以更好地满足许多不同环境的需求。”

http://www.oracle.com/technetwork/articles/servers-storage-dev/oom-killer-1911807.html