Вы отменяете какие-либо финализаторы? Когда финализатор не возвращается (возможно, вы ожидаете в любой момент другого потока), приложение может зависнуть. GC.Collect()
вызывает финализатор, но он никогда не возвращается, поскольку ожидает возврата финализатора. Это также может быть причиной утечки памяти, поскольку сборщик мусора не может завершить сборку мусора.
Решение
Вы должны быть в состоянии отладить его, когда сборщик мусора собирает и нажимает «пауза», он должен показать вам трассировку стека, где он висит. Если все идет не так, как надо, возможно, вам нужно проверить разборку, на которой висит ваше приложение.
GetTotalMemory (правда)
Этот метод вызывает сборку мусора, поэтому он такой же, как GC.Collect()
.
Обновление
Давайте посмотрим на GetTotalMemory:
public static long GetTotalMemory(bool forceFullCollection)
{
long totalMemory = GC.GetTotalMemory();
if (!forceFullCollection)
{
return totalMemory;
}
int remainingSteps = 20;
long lastMemory = totalMemory;
float num4;
do
{
GC.WaitForPendingFinalizers();
GC.Collect();
totalMemory = lastMemory;
lastMemory = GC.GetTotalMemory();
num4 = (float)(lastMemory - totalMemory) / (float)totalMemory;
}
while (remainingSteps-- > 0 && (-0.05 >= (double)num4 || (double)num4 >= 0.05));
return lastMemory;
}
Как видите, GetTotalMemory
ожидает финализаторов, поэтому это должен быть финализатор, который вешает приложение. GC.Collect()
вызывается, когда финализаторы заканчиваются, и никогда не будет вызван, потому что он никогда не проходит строку раньше.
В любой точке вашего приложения (небезопасный код? Другой поток?) Есть что-то, что выделяет много памяти, в то время как GC никогда не имеет возможности очистить существующую память.
Отказ от ответственности
Это чистое предположение, я не знаю, обрабатывает ли GC такие ситуации, но я думаю, что он не может прервать выполнение финализатора, потому что это может занять много времени, и GC не знает, просто ли он зависает. или все еще дорабатывает.