суббота, 28 января 2012 г.

Сюрприз Profiling API

На днях, при отладке профайлера на приложении выделяющим и инициализирующим массив в 2Gb (максимальный размер объекта в CLR) во время очередного GC был замечен странный кратковременный всплеск потребления памяти - выделялось дополнительно еще 2Gb (итого пиково было 4Gb). После расследования выяснилось, что на время вызова ICorProfilerCallback::ObjectReferences() CLR выделяет массив для передачи в профайлер исходящих рефернсов соответствующего объекта. Если референсы занимают эти самые 2Gb, то будут выделен массив в 2Gb. Проблема возникает только тогда, когда ICorProfilerCallback::ObjectReferences() возвращает всегда S_OK и производится полный обход графа для профайлера.

Собственно приложение (число 9 в коде подобрано для CLR 4.0 x64):

using System;

namespace AllocationTest
{
  internal class Program
  {
    private static void Main()
    {
      var tmp = new object[0x80000000U / (uint) IntPtr.Size - 9];

      for (int n = 0; n < tmp.Length; ++n)
        tmp[n] = tmp;

      Console.Write("Press any key...");
      Console.ReadKey();
      Console.WriteLine();

      GC.KeepAlive(tmp);
    }
  }
}
P.S. Если убрать в примере запонение массива, то эффекта не наблюдается.

четверг, 10 ноября 2011 г.

Как определить есть ли очередь сообщений у треда?

Оказывается все просто и не просто одновременно. Проблемы нам подкладывает само Win32 API - оно при любом удобном случае само создает очередь сообщений для треда, если ее еще не было. Про IsGUIThread() я ничего особого говорить не буду, так как он позволяет узнать то, что нам нужно, только для текущего треда. И, кстати, метод отсутствует в WinCE. На помощь нам придет PostThreadMessage(), но у него есть одна неприятная особенность - тот тред в котором вы его вызвали приобретает очередь сообщений, даром. Поэтому вызывать его для текущего треда бессмысленно. Вот и пришлось для него завести специальный, рабочий тред.

// Note: It works correctly when GetCurrentThreadId() != tid !
//       Current thread will have the message queue after this call!
bool HasThreadMessageQueue(DWORD const tid)
{
  return PostThreadMessage(tid, WM_NULL, 0, 0) || GetLastError() == ERROR_NOT_ENOUGH_QUOTA;
}

четверг, 27 октября 2011 г.

пятница, 30 сентября 2011 г.

Чем опасен managed DllMain или история одного deadlock'а

Собственно этот пост возник из-за проблемы с dotTrace. При профиляции приложения пользователя программа намертво зависала. Отладка показала, что зависание происходило точно в момент загрузки Microsoft.DirectX.Direct3D.dll внутри профайлерного эвента ModuleLoadFinished(). Другими словами виноват однозначно dotTrace.

суббота, 7 мая 2011 г.

Коммандная строка и что вы о ней знаете

Каждый разработчик сталкивался с коммандной строкой тем или иным образом. Многие даже писали батнички. Другими словами вам кажется, что вы все знаете о командной строке все. Так? Тогда скажите что будет в массиве argv для вот такой коммандной строки: 1.exe "D:\" C:\\"Program Files\"MyApp

Чтобы получить правильный ответ нужно читать тут.

пятница, 8 апреля 2011 г.

Маленький трюк в XAML

Предположим, что вы, по идейным соображениям (имя сборки меняется от проекта к проекту), не хотите явно указывать имя некой assembly в своем XAML, но хотите использовать класс оттуда. Запись типа
xmlns:RRR="clr-namespace:NNN;assembly=AAA"
вам тут уже не годиться - имя сборки ведь нужно указать точно. Как быть спросите вы? А выход есть. В assembly AAA на которую вы хотите ссылаться нужно указать следующий атрибут
[assembly: XmlnsDefinition("http://UUU", "NNN")]
а в XAML использовать следуюший синтаксис
xmlns:RRR="http://UUU"
и проблема решена.

вторник, 4 января 2011 г.

Проблемы с личными сертификатами под Windows 7 и IE8

Суть проблемы в том, что ваши сертификаты видны через менэджер сертификатов, а вот IE8 чихал на это и всегда показывает пустой список. Соответственно ничего не работает. Оказывается это известная проблема и для нее есть хотфикс, но он особо не офишируется и не доступен через центр обновления. Имя ему - KB977222.

P.S. Проблема актуальна и для Windows Server 2008.

P.P.S. Напоролся на это при настройке КриптоПро CSP.

суббота, 1 января 2011 г.

О культуре работы с реестром (Продолжение)

И снова проблемы у наших пользователей (слава богу хоть не массовые), и снова проклятые переменные окружения, которые не чистятся конкурентами. На этот раз все упирается только в IIS 7.x. Оказывается доблестные конкуренты модифицируют переменные окружения для аккаунтов под которыми запускаются пулы приложений. Пара часиков и все готово - версия dotTrace Performance 4.0.2 будет содержать фикс.

Предыдущая серия...