Вызов WCF, вызывающий утечку памяти - PullRequest
1 голос
/ 05 июля 2011

У нас возникли проблемы с вызовом служб WCF, который вызывает утечку памяти.В нашем исследовании мы думаем, что мы правильно вызываем сервис и правильно обрабатываем возникающие из него ошибки.Мы даже подтвердили это с помощью статей MSDN и примера кода WCF, полученного с веб-сайта MS.

Вот пример кода, который вызывает утечку.При вызове SaveAssociation код на другой стороне вызывает исключение.Это заставляет канал входить в состояние ошибки.Первый оператор catch перехватывает исключение (SystemException) и вызывает Abort () на клиенте, который должен немедленно прервать сеанс и закрыть клиентское соединение.Однако, наблюдая, как этот процесс запускает этот код снова и снова в цикле, мы просто видим, что память, используемая процессом, поднимается и поднимается.

var client = new FrameworkServiceReference.MAServiceClient();

// Get User domain name
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";

OperationContextScope a1 = new OperationContextScope(client.InnerChannel);
MessageHeader<string> customHeaderAppID = new MessageHeader<string>("Account Management");
System.ServiceModel.Channels.MessageHeader a2 = customHeaderAppID.GetUntypedHeader("application", "http://www.ma.com");
OperationContext.Current.OutgoingMessageHeaders.Add(a2);

try
{
            client.SaveAssociation(association);
            client.Close();
}
catch (SystemException se)
{
            client.Abort();
}
catch (Exception ex)
{
            client.Abort();
}

Вот ошибка, которую мы получаем…

System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Object reference not set to an instance of an object. (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Multiview.Business.Core.CoreObject.ValidateItem(String Item, String Value)
   at Multiview.Business.Core.User.UpdateUser()
   at Multiview.Business.Core.User.Save()
   at Multiview.Core.ServiceLibrary.MultiviewService.SaveCRMUser(User user, Guid CRMGuid)
   at SyncInvokeSaveCRMUser(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
   at System.ServiceMode...).

Что можно сделать, чтобы остановить эту утечку?

Ответы [ 2 ]

2 голосов
/ 05 июля 2011

Если память на сервере увеличивается, проверьте журнал сервера.Возможно, у возвращаемого вами объекта есть круговая ссылка.Это означает, что когда он возвращается, сервер генерирует переполнение стека при сериализации объекта.

Попробуйте настроить службу с помощью:

IncludeExceptionDetailInFaults=true

и создать несколько журналов (сервер и клиентсторона):

<system.diagnostics>
<sources>
  <source name="System.ServiceModel" switchValue="Error, ActivityTracing" propagateActivity="true">
    <listeners>
      <add name="xml" />
    </listeners>
  </source>
  <source name="CardSpace">
    <listeners>
      <add name="xml" />
    </listeners>
  </source>
  <source name="System.IO.Log">
    <listeners>
      <add name="xml" />
    </listeners>
  </source>
  <source name="System.Runtime.Serialization">
    <listeners>
      <add name="xml" />
    </listeners>
  </source>
  <source name="System.IdentityModel">
    <listeners>
      <add name="xml" />
    </listeners>
  </source>
</sources>
<sharedListeners>
  <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\t\mylog.svclog" />
</sharedListeners>
</system.diagnostics>
1 голос
/ 05 июля 2011

Если у вас есть проблема с утечками памяти, вы должны начать с некоторого профилировщика памяти и выяснить, какие объекты живут в вашей памяти.Это приведет вас к источнику утечки.

Вы можете начать с того, что OperationContextScope является одноразовым.

...