2

我一直在与似乎阻止释放自由对象的内存泄漏作斗争。

最近我的 webapp 在 w3wp.exe 的内存达到 1100 MB 后开始崩溃。在事件日志中,我发现了一个 db 连接超时错误,因为连接池已满(我将其设置为 300 个连接)。

使用 windbg,执行 dumpheap -stat 显示有许多“免费”类型的未发布对象:

00000071f70ac438 10300 478192918 免费

所以 10300 个免费对象占用了将近 500MB 的空间。

在一些更大的自由对象(加上大小)上做一个 !gcroot 给我这些:

!gcroot 00000071f7d63b78+0x509778
Thread 1bf4:
    000000765f43caf0 000007faab4a7f13 System.Data.SqlClient.SqlCommand..ctor(System.Data.SqlClient.SqlCommand)
        rsi: 
            ->  00000071f6cfd0f8 System.Data.SqlClient.SqlCommand
            ->  00000071f6cff710 System.Data.SqlClient.SqlParameterCollection
            ->  00000071f6cff738 System.Collections.Generic.List`1[[System.Data.SqlClient.SqlParameter, System.Data]]
            ->  00000071f6cff760 System.Object[]
            ->  00000071f6cff7a0 System.Data.SqlClient.SqlParameter
            ->  00000071f826d2f0 System.String

    000000765f43cc60 000007faa65f5832 System.Data.EntityClient.EntityCommandDefinition..ctor(System.Data.Common.DbProviderFactory, System.Data.Common.CommandTrees.DbCommandTree)
        rbp+8: 000000765f43cc98 (pinned)
            ->  00000071f83aef08 System.Collections.Generic.List`1[[System.Data.Query.PlanCompiler.ProviderCommandInfo, System.Data.Entity]]
            ->  00000071f83aef30 System.Object[]
            ->  00000071f83aeee0 System.Data.Query.PlanCompiler.ProviderCommandInfo
            ->  00000071f6cfc698 System.Data.Common.CommandTrees.DbQueryCommandTree
            ->  00000071f6cfc5b0 System.Data.Common.CommandTrees.DbProjectExpression
            ->  00000071f6cf5f98 System.Data.Common.CommandTrees.DbExpressionBinding
            ->  00000071f6cf5f40 System.Data.Common.CommandTrees.DbSortExpression
            ->  00000071f6cf5de8 System.Data.Common.CommandTrees.DbExpressionBinding
            ->  00000071f6cf5cd8 System.Data.Common.CommandTrees.DbProjectExpression
            ->  00000071f6ced718 System.Data.Common.CommandTrees.DbExpressionBinding
            ->  00000071f6ced600 System.Data.Common.CommandTrees.DbJoinExpression
            ->  00000071f6ceb3f0 System.Data.Common.CommandTrees.DbExpressionBinding
            ->  00000071f6ceb398 System.Data.Common.CommandTrees.DbLimitExpression
            ->  00000071f6ceb340 System.Data.Common.CommandTrees.DbFilterExpression
            ->  00000071f6ceb310 System.Data.Common.CommandTrees.DbAndExpression
            ->  00000071f6ceb2e0 System.Data.Common.CommandTrees.DbComparisonExpression
            ->  00000071f6ceb2b8 System.Data.Common.CommandTrees.DbParameterReferenceExpression
            ->  00000071f826d2f0 System.String

    000000765f43cc60 000007faa65f5832 System.Data.EntityClient.EntityCommandDefinition..ctor(System.Data.Common.DbProviderFactory, System.Data.Common.CommandTrees.DbCommandTree)
        rbp+190: 000000765f43ce20
            ->  00000071f6ce9fb0 System.Data.Common.CommandTrees.DbQueryCommandTree
            ->  00000071f6ce9f80 System.Data.Common.CommandTrees.DbLimitExpression
            ->  00000071f6ce9e98 System.Data.Common.CommandTrees.DbProjectExpression
            ->  00000071f6ce8100 System.Data.Common.CommandTrees.DbExpressionBinding
            ->  00000071f6ce78f0 System.Data.Common.CommandTrees.DbFilterExpression
            ->  00000071f8273be8 System.Data.Common.CommandTrees.DbAndExpression
            ->  00000071f8273bb8 System.Data.Common.CommandTrees.DbComparisonExpression
            ->  00000071f826d320 System.Data.Common.CommandTrees.DbParameterReferenceExpression
            ->  00000071f826d2f0 System.String

    000000765f43cf70 000007faa655da7d System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(System.Nullable`1<System.Data.Objects.MergeOption>)
        r12: 
            ->  00000071f6ce2768 System.Data.Objects.ELinq.ELinqQueryState
            ->  00000071f6ce7aa0 System.Data.Objects.ObjectParameterCollection
            ->  00000071f6ce7ad0 System.Collections.Generic.List`1[[System.Data.Objects.ObjectParameter, System.Data.Entity]]
            ->  00000071f6ce7af8 System.Object[]
            ->  00000071f8273b80 System.Data.Objects.ObjectParameter
            ->  00000071f826d2f0 System.String

似乎某些带有 EF 的数据上下文被固定在某个地方。问题是:在哪里以及为什么?我的 webapp 充满了 ef 调用。

4

1 回答 1

0

我不太确定您的具体情况(我可能需要查看更多代码才能获得更好的想法),但是很多人在使用 EF 时会出现内存泄漏,因为他们持有上下文的时间过长。EF 保留其先前在上下文生命周期内查询的所有实体的快照,以进行更改跟踪。

我要注意的是,您在查询后直接处理您的上下文,如果您using在上下文周围使用块,则应该这样做。您有大量内存使用并且您的连接池已满这一事实向我表明,您可能在某个地方有一个正在创建但从未处置的上下文。

于 2013-07-26T13:26:06.757 回答