Проблема использования памяти при использовании HTTPS для веб-сервисов или веб-запросов - PullRequest
2 голосов
/ 10 января 2012

РЕДАКТИРОВАТЬ: После долгого обсуждения в комментариях, кажется, что мой первоначальный вопрос на самом деле не отражает происходящее. Вот краткое изложение того, где я сейчас нахожусь:

  • При использовании HTTPS есть то, что я бы назвал резким скачком в пространстве виртуальной памяти моего приложения (обычно от 50 МБ до 200 МБ) при первом запросе HTTPS (вызов веб-службы, WebClient.DownloadFile () и т. Д. ) сделано
  • В то же время ядро ​​ЦП также переходит почти на 100%. Обычно это длится всего несколько секунд, но я видел, что это длится дольше
  • Вполне возможно, что это просто стоимость использования HTTPS, но я был удивлен этим, так как я никогда не замечал этого раньше в других приложениях (а другие разработчики в моей команде никогда не замечали этого в этом приложении, который использует HTTPS задолго до того, как я поднялся на борт).
  • Кикер: это происходит не на всех машинах, а на большинстве. Если бы это происходило последовательно на каждой машине, я бы с большей готовностью принял это как «затраты на ведение бизнеса». Но поскольку между некоторыми машинами, работающими с одним и тем же кодом и ОС, существует определенная разница, я хотел бы понять, почему это так, поскольку это либо а) позволит нам смягчить поведение, либо б) объяснить его таким образом, чтобы нетехнические сведения о том, что на самом деле это не «проблема», так как объяснение того, что диспетчер задач Windows показывает виртуальную память и не обязательно активно используемую физическую память, пока не является удовлетворительным: /

Я оставил исходный пост без изменений на тот случай, если кому-то интересно, но он больше фокусируется на веб-сервисах, которые на самом деле не являются корнем проблемы.

Заранее благодарим за дальнейшее понимание!


Мы наблюдаем резкое увеличение использования памяти всякий раз, когда наше приложение впервые обращается к нашему веб-сервису по протоколу https. Специфика зависит от машины, но в качестве примера мы можем увидеть, как наше приложение перепрыгивает с ~ 50 МБ до более 250 МБ, когда выполняется первый вызов веб-службы, и использование никогда не снижается. Последующие вызовы не приводят к другому такому прыжку. Я могу воспроизвести это поведение с помощью приведенного ниже кода (не относится к нашему приложению) и общедоступной веб-службы, которой мы не владеем, поэтому она, похоже, не зависит от нашего клиентского и серверного кода.

Интересно, что в моем тестовом приложении я не наблюдаю этот скачок в Windows XP (наше приложение в настоящее время развернуто только в Windows 7). Мы также не видим его на каждой машине разработки / тестирования в офисе (но мы делаем на большинстве), и в настоящее время у нас нет способа извлечь эту информацию с машин в «реальном мире».

Мне не удалось определить, что именно выделяется, но несколько профилировщиков дали понять, что оно находится в собственной (не управляемой) памяти. Анализ некоторых дампов WinDbg с использованием DebugDiag заставляет меня поверить, что в crypt32.dll выделяется много памяти, которая не освобождается. В некоторой степени это имеет смысл (https подразумевает сертификаты, безопасность и т. Д., И, вероятно, все, что загружается, кэшируется, поэтому последующие вызовы не приводят к дополнительным переходам), но мне трудно поверить, что это на самом деле просто стоимость использования https для веб-службы.

Я знаю, что будут ответы от "если более высокое использование памяти не вызывает проблем, зачем беспокоиться?" лагерь. В целом я согласен - цифры использования памяти в диспетчере задач часто не указывают на то, работает ли приложение так, как задумано. Если бы приложение использовалось исключительно внутри компании, я мог бы жить с этим, пока это не является симптомом других проблем. Но наше приложение развернуто на потребительских машинах, поэтому нам нужно беспокоиться о восприятии проблемы так же, как и о реальной проблеме. Так что, если есть какой-то способ исправить это, я был бы очень признателен!

Наконец, веб-сервис, который я использую в тестовом коде ниже, доступен здесь: http://ws.cdyne.com/emailverify/Emailvernotestemail.asmx?wsdl. Код для EmailVerNoTestEmail был создан с использованием инструмента wsdl.exe с небольшой модификацией передачи URL-адреса в качестве параметра. конструктору, а не жестко его кодировать (чтобы http / https можно было задавать на лету).

public static void Main(string[] args)
{
    const string urlSuffix = "://ws.cdyne.com/emailverify/Emailvernotestemail.asmx";
    string protocol = null;
    while(protocol == null)
    {
        Console.Write("Enter protocol (http, https): ");
        var line = Console.ReadLine();
        if (line != null) line = line.ToLower();
        if (line == "http" || line == "https")
            protocol = line.Trim();
    }
    var url = protocol + urlSuffix;
    Console.WriteLine("Using URL: " + url);
    Console.Out.Flush();

    var service = new EmailVerNoTestEmail(url);

    Console.WriteLine("Press any key to make the web service call...");
    Console.ReadKey(true);

    Console.WriteLine("Calling web service...");
    var resp = service.VerifyEmail("test@gmail.com", "test");
    Console.WriteLine("Response: " + resp);

    Console.WriteLine("Press any key to exit.");
    Console.ReadKey(true);
}

1 Ответ

0 голосов
/ 10 января 2012

Если система не подвержена стрессу, естественно, что она остается на определенном уровне памяти. В ОС есть эвристика, которая определяет, сколько памяти необходимо, и выделяет эту высшую точку больше, чем нужно. Зачем? Это дорого для выделения и освобождения памяти, и если программа может работать в собственной изолированной программной среде, которая была предоставлена, зачем уменьшать ее, если система не загружена.

Как вы упомянули, проблема не в объеме выделенной памяти, а в утечке памяти. Я предлагаю вам запустить perfmon и следить за утечками; Узнайте о том, на что обращать внимание в статье MSDN CLR Исследование проблем с памятью .

РЕДАКТИРОВАТЬ : ( Это совет, который я дал ранее, но может быть уместным / извините за дублирование темы )

Чтобы увидеть явный признак утечек памяти, запускается perfmon и для этих символов просматривается Private Bytes в perfmon. См. Определение и предотвращение утечек памяти в управляемом коде , чтобы начать этот процесс.

Еще один используемый процесс находится на вкладке «Процессы» диспетчера задач Windows. (Просмотр + Выбор столбцов), отметьте дескрипторы, объекты GDI и объекты USER. Соблюдайте эти значения для вашей программы. Если есть утечка ручки, вы увидите, что один из них постоянно поднимается. GDI, по всей вероятности, по этим сценариям.

В общем, когда ОС запускает приложение, она пытается определить, сколько памяти используется. Он выделит больше памяти для приложения, которое требуется приложению в данный момент. Это связано с тем, что выделение / освобождение памяти является интенсивной операцией процессора. Зачем параллельно то, что нужно приложению, когда оно может находиться в пуле памяти, что позволит ему, приложению, расширяться и сжиматься без вмешательства операционной системы. Экономит на циклах.

Разработчик видит высокую оценку памяти. Если система не находится под напряжением, система не будет восстанавливать памяти и сохранит отметку максимальной воды. На этом форуме есть много сообщений, в которых пользователи говорят, что обработка завершена, память очищена, но ОС все еще показывает мое приложение в точке памяти X, когда она должна быть точкой памяти M (ниже). Пользователи Winform сообщают то же самое, но если кто-то минимизирует приложение, внезапно сообщаемое использование памяти падает до этого уровня М. Это сделано по замыслу. Минимизация предполагает, что приложению не нужна память, поскольку оно не будет взаимодействовать с пользователем, и ОС исправит эту проблему. Если это не winform и ОС не нагружена, приложение остается на отметке X.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...