Как заставить сборщик мусора в Mono делать что-нибудь полезное? Внизу этого поста находится простая тестовая программа C #, которая генерирует две большие строки. После генерации первой строки переменная разыменовывается, область действия закрывается, а сборщик мусора запускается вручную.Несмотря на это, используемая память не уменьшается, и программа взрывается с исключением нехватки памяти во время построения второй строки.
Необработанное исключение: OutOfMemoryException [ERROR] FATAL UNHANDLED ИСКЛЮЧЕНИЕ: System.OutOfMemoryException: недостаточно памяти в (оболочка от управляемого к собственному) строка: InternalAllocateStr (int) at System.String.Concat (System.String str0, System.String str1) [0x00000] в: 0 в GCtest.Main (System.String [] args) [0x00000] in: 0
После исследования я обнаружил переключатель - gc = sgen
для Mono, который использует другой алгоритм сборки мусора. Это еще хуже, генерируя следующую трассировку стека:
Stacktrace:
в строке (управляемая оболочкой для собственной) .InternalAllocateStr (int) <0xffffffff> в строке.Concat (строка, строка) <0x0005b> в GCtest.Main (string []) <0x00243> в (запуск оболочки во время выполнения) .runtime_invoke_void_object (объект, intptr, intptr, intptr) <0xffffffff>
Собственная трассировка стека:
0 моно-sgen 0x000bc086 mono_handle_native_sigsegv + 422 1 моно-sgen
0x0000466e mono_sigsegv_signal_handler + 334 2 libsystem_c.дилиб
0x913c659b _sigtramp + 43 3 ???
0xffffffff 0x0 + 4294967295 4 моно-sgen
0x0020306d mono_gc_alloc_obj_nolock + 363 5 моно-sgen
0x0020394a mono_gc_alloc_string + 153 6 mono-sgen
0x001c9a10 mono_string_new_size + 147 7 mono-sgen
0x0022a6d1 ves_icall_System_String_InternalAllocateStr + 28 8 ???
0x004c450c 0x0 + 4998412 9 ???
0x004ceec4 0x0 + 5041860 10 ???
0x004c0f74 0x0 + 4984692 11 ???
0x004c1163 0x0 + 4985187 12 моно-sgen
0x00010164 mono_jit_runtime_invoke + 164 13 mono-sgen
0x001c5791 mono_runtime_invoke + 137 14 mono-sgen
0x001c7f92 mono_runtime_exec_main + 669 15 mono-sgen
0x001c72cc mono_runtime_run_main + 843 16 моно-sgen
0x0008c617 mono_main + 8551 17 моно-sgen
0x00002606 начало + 54 18 ???
0x00000003 0x0 + 3Отладочная информация из gdb:
/tmp/mono-gdb-commands.2aCwlD:1: Ошибка в исходном командном файле: невозможно для отладки себя
Получил SIGSEGV при выполнении собственного кода. Обычно это указывает на смертельный исход. ошибка в среде выполнения mono или одной из собственных библиотек, используемых вашим заявление.
/Users/fraser/Documents/diff-match-patch/csharp/GCtest.command: строка 12: 41011 Прерывание прерывания: 6 mono --gc = sgen GCtest.exe
Вот код:
using System;
public class GCtest {
public static void Main(string[] args) {
Console.WriteLine("Memory: " + (GC.GetTotalMemory(true) / 1024) + " KB");
{
// Generate the first string.
string text1 = "hello old world.";
for (int i = 0; i < 25; i++) {
text1 = text1 + text1;
}
// Dereference variable.
text1 = null;
// Drop out of scope.
}
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Memory: " + (GC.GetTotalMemory(true) / 1024) + " KB");
// Generate the second string.
string text2 = "HELLO NEW WORLD!";
for (int i = 0; i < 25; i++) {
text2 = text2 + text2;
}
Console.WriteLine("Memory: " + (GC.GetTotalMemory(true) / 1024) + " KB");
}
}