2013-07-25 1 views
2

Я боролся с утечкой памяти, которая, похоже, освобождает свободные объекты от выпуска.Утечка памяти: как найти причину, по которой объект был закреплен

Недавно мой webapp начал сбой после того, как память w3wp.exe достигла 1100 МБ. В журнале событий я обнаружил ошибку тайм-аута соединения db, потому что пул соединений был заполнен (я установил его на 300 соединений).

С WinDbg, делая dumpheap -stat показывает, что есть много неизданных объектов типа 'Free':

00000071f70ac438 10300 478192918 Free

так 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 

Похоже некоторые DataContext с EF получает возлагали куда-то. Вопрос в том, где и почему? Мой webapp заполнен вызовами ef.

+1

В каком поколении содержатся ваши бесплатные объекты? Вы можете узнать, запустив! Sosex.dumpgen -stat, где может быть 0,1,2 или 3/LOH. –

+0

хороший момент, и приятное расширение спасибо. 382MB в гене 0 делится только на 323 объекта и 60MB в gen 2. Есть ли способ увидеть один из этих 323 объектов? –

+1

! Dumpgen 0 -бесплатно, чтобы увидеть БЕСПЛАТНЫЕ объекты. ! mfrag, чтобы увидеть закрепленные объекты. –

ответ

0

Я не слишком уверен в вашем конкретном сценарии (и мне, вероятно, нужно будет увидеть больше кода, чтобы получить лучшую идею), но многие люди получают утечки памяти с помощью EF, поскольку они слишком долго удерживают контекст. EF хранит моментальный снимок всех объектов, которые ранее запрашивались для жизни контекста, чтобы отслеживать изменения.

Что бы я хотел, так это то, что вы избавляетесь от своих контекстов прямо после запроса, если вы используете блоки using вокруг контекста, это должно сделать это. Тот факт, что у вас много использования памяти, и ваш пул соединений полна, подсказывает мне, что, возможно, где-то у вас есть контекст, который создается и никогда не используется.

+0

Спасибо, я поместил их в использование блоков исключительно. Но приятно быть уверенным, что это вызывает, поэтому мой вопрос. –

Смежные вопросы