Утечка памяти при использовании SSL и клиентских сертификатов с объектом HttpWebRequest

Я использую объект HttpWebRequest для загрузки файлов с использованием SSL с сертификатом клиента, у меня есть действующий сертификат на моем сервере, в моем приложении возникла проблема с утечкой памяти, и Microsoft опубликовала что-то, связанное с проблемой, по следующей ссылке:

ИСПРАВЛЕНИЕ: утечка памяти при использовании SSL и клиентских сертификатов с объектом HttpWebRequest

Есть ли какой-нибудь обходной путь, чтобы избежать этой утечки памяти, особенно потому, что каждый запрос потребляет 8 КБ утечки памяти, это приведет к тому, что мое приложение будет потреблять так много памяти.


 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
 ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);
 request.Method = "POST";
 request.ContentType = "text/xml; charset=utf-8";

утечки памяти были обнаружены с помощью .NET Memory Profiler, и он показывает, что объект HttpWebRequest имеет массив байтов, который приводит к утечке памяти, я размещение объектов потока и запроса.

Я попробовал этот случай с SSL и without SSL, утечки исчезли в запросах, отличных от SSL.


person Ahmad Kayyali    schedule 21.05.2011    source источник
comment
Мы не можем помочь вам набрать номер телефона.   -  person Hans Passant    schedule 21.05.2011
comment
если вы заметили Идентификатор статьи: 831578 - Последнее изменение: 25 октября 2005 г. - Редакция: 1.5 прошло 6 лет, я подумал, может быть, кто-то сталкивался с такой же проблемой.   -  person Ahmad Kayyali    schedule 21.05.2011
comment
Эта утечка относится только к .NET 1.1. Почему вы считаете, что сталкиваетесь с этим? (при условии, что вы не используете 1.1)   -  person blowdart    schedule 21.05.2011
comment
@blowdart: потому что, когда я перестаю использовать SSL, утечки памяти больше не существует.   -  person Ahmad Kayyali    schedule 21.05.2011
comment
Но вы не сказали, как вы обнаруживаете утечку, в конце концов, трудно определить утечку в управляемом коде, это может быть просто GC, который еще не подметает. Или далее по линии вы выполняете манипуляции с потоком, а не избавляетесь от потока. Для этого требуется гораздо больше информации, прежде чем кто-либо сможет предложить помощь - как вы обнаруживаете утечку, каковы числа, дампы стека Windbg, остальная часть кода вокруг этих четырех строк и т. д. и т. д. Тот факт, что статья базы знаний не была обновлена, указывает на то, что исправление было внедрено в 2.0 и более поздние версии.   -  person blowdart    schedule 21.05.2011
comment
@blowdart: см. обновленный вопрос.   -  person Ahmad Kayyali    schedule 21.05.2011


Ответы (2)


просто установите для свойства AllowWriteStreamBuffering вашего объекта HttpWebRequest значение false:

request.AllowWriteStreamBuffering = false;
request.AllowAutoRedirect = false;

Примечание. Framework кэширует сеансы SSL по мере их создания и пытается повторно использовать кэшированный сеанс для нового запроса, если это возможно. При попытке повторного использования сеанса SSL платформа использует первый элемент ClientCertificates (если он есть) или пытается повторно использовать анонимные сеансы, если ClientCertificates пуст.

Другое Примечание. Из соображений производительности не следует добавлять сертификат клиента в HttpWebRequest, если только вы не знаете, что сервер запросит его. Пример кода, иллюстрирующий перечисление сертификатов в хранилище сертификатов клиента, см. в классе X509Certificate2Collection.

Или попробуйте использовать это:

request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); 
person Yahya Younes    schedule 22.05.2011
comment
@Yahya Yahya - есть ли способ определить, запрашивает ли сервер сертификат клиента? - person ianbeks; 18.04.2013

Вы можете использовать WinDbg, отладчик, который является частью Windows SDK, чтобы лучше изучить, как для вас управляется память. Хотя это не так удобно, как сторонние варианты, это позволяет вам спуститься ниже и выяснить, действительно ли то, что вы видите, является утечкой. Нет действительно простого способа определить, в чем заключается ваша проблема, вы создаете новые экземпляры ValidateRemoteCertificate, которые, как я полагаю, являются вашим кодом, и сами по себе не могут освобождать все, что он использует, что, в свою очередь, может привести к тому, что GC не будет очищать запрос.

Для начала вы можете прочитать

Если после этого вы действительно считаете, что это ошибка .NET framework, а не в вашем собственном коде, сообщите об этом. Это можно сделать несколькими способами: с помощью Connect. отправить инцидент в службу поддержки в Microsoft. Если вы пойдете по маршруту обращения в службу поддержки, вам понадобится кредитная карта. Если ваша проблема связана с ошибкой в ​​.NET framework, с вас не будет взиматься плата.

person blowdart    schedule 21.05.2011