Это 32-битный моно?Я полагаю, что описанное вами поведение вызвано тем, что с Boehm GC, по крайней мере, стек сканируется консервативно.Это означает, что значения на нем обрабатываются как если бы они были указателями.Если какое-то такое значение указывает на объект (или его подчиненный), то этот объект не будет собран.Теперь понятно, почему большие объекты здесь проблематичны - они могут легко заполнить виртуальное адресное пространство 32-битного процесса, у нас есть большой шанс, что какое-то значение в стеке указывает где-то в нем, и весь объект не собирается.Каковы источники таких противных фальшивых указателей?Наиболее известны мне хэши, случайные значения или дата / время (обычно int
с низким).
Как заставить сборщик мусора в Mono делать что-нибудь полезное?
Вы использовали правильный метод, но я думаю, что вы столкнулись с проблемой, описанной выше.Обычные программы не так сильно страдают, потому что (так) огромные объекты довольно редки.Завтра я также протестирую его на 64-битном Mono.
Тем не менее, возникает вопрос, который возникает автоматически: почему проект Mono не создает еще один GC, который не будет консервативным?Такой сборщик мусора, как вы уже нашли, sgen.Я думаю, что целью sgen, помимо того, что он является точным сборщиком, является тот факт, что он уплотняет, что очень важно для долго работающих приложений, и что у него (иногда намного) лучшая производительность.Однако sgen все еще находится в стадии бета-тестирования, здесь и там можно наблюдать сбои.Кроме того, функция точного сканирования стека была включена и выключена в различных версиях Mono, иногда проходила некоторая регрессия, поэтому вы можете обнаружить, что более старая версия Mono работает лучше, чем более новая.Тем не менее, sgen активно развивается (как можно найти историю коммитов на github) и вскоре должен занять место сборщика мусора по умолчанию в Mono.Что в конечном итоге должно решить проблемы, подобные описанной.
Кстати, например, моя версия Mono (все еще 32-битная) проходит этот тест с sgen:
$ mono --gc=sgen GCTest.exe
Memory: 4098 KB
Memory: 4140 KB
Memory: 1052716 KB
Надеюсь, это было полезно, спросите, есличто-то было неясно (особенно из-за моего второго качественного английского).
Редактировать:
На моей 64-битной машине Boehm работает хорошо:
$ mono GCTest.exe
Memory: 132 KB
Memory: 280 KB
Memory: 1048860 KB
(естественно тоже сген).Это Mono 2.10.5 в Linux.