我的32位基于Web服务的基于LLBLGen的数据访问应用程序在专用的64位计算机上独立运行。当进程释放几乎所有分配的空间(高达1,5GB)并且从那一点再次继续增长时,它的物理内存消耗稳定增长到大约2GB。页面输入值或其他页面文件使用参数没有可观察到的增加,因此看起来内存被释放而不是被换出到页面文件。我在想这是什么样的个人资料?实际上没有什么可以防止进程占用所有内存,另一方面内存释放周围存在不可接受的http内部错误 - 可能是清理阻止了有用的工作。如果上述情况首先是一种可接受的行为,那么使清理变得不那么突兀的好策略是什么。
答案 0 :(得分:2)
听起来你有内存泄漏,进程一直在泄漏内存,直到它因内存不足而崩溃,然后由服务器自动重启。
1.5GB大约是32位进程在用完地址空间之前可以分配的最大内存量。
要寻找的事情:
答案 1 :(得分:1)
您是否有可能不处理各种一次性物品(特别是与DB相关的物品)。这会留下它们,可能会占用大量非托管资源,直到GC运行并调用它们的终结器。
值得对你的进程运行perfmon,并查看某些关键资源(如句柄)是否有稳定增长,或者数据库提供程序是否公开性能计数器,然后是连接或打开结果集。
答案 2 :(得分:1)
我同意edg的答案的第一部分,但他说:
“通过将对象设置为null 死了你可以鼓励GC 重用那些消耗的内存 对象,这限制了增长 消耗记忆。“
不正确。您永远不需要将对象设置为null,因为GC最终会在超出范围后收集对象。
的答案中讨论过答案 3 :(得分:0)
垃圾收集器在释放对象时不会自动释放内存,它会保留内存以帮助最大限度地降低未来malloc的费用。
当触发低内存条件时,内存将返回到操作系统,并且在查看任务管理器时您将看到更多可用内存。这通常发生在2GB标记左右,如果使用relevant switch,则通常为3GB。
<contentious>
通过将对象设置为null时,可以鼓励GC重用这些对象消耗的内存,这限制了内存消耗的增长。
但是你应该将哪些对象设置为null?大对象,大型集合,经常创建的对象。
</contentious>
编辑:有证据支持将对象设置为null的值。有关详细信息,请参阅this。当然没有需要将对象设置为null,重点是它是否有助于内存管理?
编辑:如果存在这样的事情而不是继续发表意见,我们需要最近的基准。
答案 4 :(得分:0)
不要使用Arraylists(垃圾收集不与它们一起工作),而是使用通用列表
其他常见错误是在web.config Debug = true中,这会消耗大量内存,将选项更改为“false”。
要做的其他事情是使用CLRProfiler来追踪问题。
祝你好运, 佩德罗答案 5 :(得分:0)
确保您没有提供项目的调试版本。有一个功能*,当你有一个调试版本时,如果你实例化包含事件定义的任何对象,即使你没有引发事件,它也只能无限期地保存一小段内存。随着时间的推移,这些小块内存将耗尽您的内存池,直到它最终重新启动Web进程,然后重新开始。
*我称这是一个功能(而不是一个bug),因为它自.Net 2开始以来一直存在(不存在于.Net 1.1中),并且没有修补它的补丁。内存泄漏必须归因于调试时需要的一些功能。
答案 6 :(得分:0)
我们遇到了类似的情况并改变了我们所有的数据库连接以使用try / catch / finally方法。 Try用于执行代码,catch用于错误收集,最后用于关闭所有变量和数据库连接。
internal BECollection<ReportEntity> GetSomeReport()
{
Database db = DatabaseFactory.CreateDatabase();
BECollection<ReportEntity> _ind = new BECollection<ReportEntity>();
System.Data.Common.DbCommand dbc = db.GetStoredProcCommand("storedprocedure");
try
{
SqlDataReader reader = (SqlDataReader)db.ExecuteReader(dbc);
while (reader.Read())
{
//populate entity
}
}
catch (Exception ex)
{
Logging.LogMe(ex.Message.ToString(), "Error on SomeLayer/SomeReport", 1, 1);
return null;
}
finally
{
dbc.Connection.Close();
_ind = null;
}
return _ind;
}
答案 7 :(得分:0)
我的第一个猜测是内存泄漏。我的第二个猜测是它是正常的行为 - 在你有巨大的内存压力之前,GC不会被触发。唯一可以确定的方法是使用分析器和PerfMon之类的组合。一些网站:
此外,我会确保您没有在调试模式下运行(如前所述)。
就HTTP错误而言 - 假设您在服务器GC模式下运行,它会尝试尽一切可能阻止请求。有趣的是找出那些HTTP错误 - 这不是我过去看到的正常行为,并且可能指出你问题的根源。