Можно использовать AppDomain. CurrentDomain. UnhandledException для получения события.
Виртуальная память, доступная процессу, составляет 2 ГБ из адресного пространства 4 ГБ. Каждый поток по умолчанию резервирует около 1 МБ пространства виртуальной памяти для своего стека. Таким образом, приложения win32 имеют ограничение в 2000 живых потоков, прежде чем виртуальная память будет исчерпана.
Виртуальная память - это память, которую приложения получают в современных ОС с виртуальной памятью, таких как Windows. Что происходит в Win32, так это то, что вашему приложению предоставляется виртуальное адресное пространство 2 ГБ. Когда ваша программа вызывает new или malloc, после туннелирования через несколько уровней для вашего приложения выделяется место НА ДИСКЕ - в файле подкачки. Когда инструкции ЦП пытаются получить доступ к этой памяти, возникают аппаратные исключения, и ядро выделяет физическую оперативную память для этой области и считывает содержимое из файла подкачки. Таким образом, независимо от физической ОЗУ на ПК, каждое приложение считает, что имеет доступ ко всем 2 ГБ. Виртуальная память - это подсчет того, сколько из ваших 2 ГБ пространства было использовано.
Каждый поток (см. Выше) резервирует 1 МБ виртуального адресного пространства для увеличения своего стека. Большая часть этого 1 МБ - это просто зарезервированное пространство (надеюсь) без поддержки ОЗУ или файла подкачки.
Когда вы закрываете дескриптор потока, вы НЕ закрываете поток. потоки завершаются другим потоком, вызывающим TerminateThread (что приводит к утечке стека потоков и некоторых других ресурсов, поэтому НИКОГДА не используйте его), самим вызовом ExitThread () или выходом из своего ThreadProc.
Итак, с ограничением 2000 вызовов, несравнимый CoInitialize и CoUninitialize, я бы сказал, что ваши потоки не завершаются чисто или вообще не завершаются. Каждый из 2000 рабочих потоков застревает на каком-то этапе работы, а не завершается после завершения своей работы.
Функции _beginthreadex
/ _endthreadex
не закрывают автоматически дескриптор потока, поэтому вы должны вызвать функцию win32 CloseHandle
, чтобы закрой его. Дескриптор - это значение, возвращаемое функцией _beginthreadex
. Если вместо этого вы используете _beginthread
/ _endthread
, дескриптор будет закрыт автоматически.
Что касается виртуальной памяти: это память, которая была зарезервирована, но еще не обязательно используется. Утечка памяти (или, по крайней мере, ее часть) связана с утечкой дескриптора. Когда последний дескриптор потока закрывается, Windows освобождает зарезервированную для него виртуальную память.