Как получить сборщик мусора в Mono, чтобы сделать что-нибудь полезное? В нижней части этого сообщения находится простая тестовая программа С#, которая генерирует две большие строки. После создания первой строки переменная разыменовывается, и область действия завершается, и сборщик мусора запускается вручную. Несмотря на это, используемая память не уменьшается и программа взрывается с исключением из памяти во время построения второй строки.
Необработанное исключение: исключение OutOfMemoryException [ОШИБКА] FATAL UNHANDLED ИСКЛЮЧЕНИЕ: System.OutOfMemoryException: Недостаточно памяти (обертка строка, управляемая навстречу): InternalAllocateStr (int) в System.String.Concat(System.String str0, System.String str1) [0x00000] в: 0 на GCtest.Main(System.String [] args) [0x00000] в: 0
После исследования я нашел переключатель --gc=sgen
для Mono, который использует другой алгоритм сбора мусора. Это еще хуже, создавая следующую трассировку стека:
StackTrace:
at (wrapper managed-to-native) string.InternalAllocateStr(int) < 0xffffffff > в строке. Конкат (строка, строка) < 0x0005b > в GCtest.Main(строка []) < 0x00243 > at (завершение выполнения оболочки).runtime_invoke_void_object (объект, intptr, intptr, intptr) < 0xffffffff >
Нативная стек:
0 mono-sgen 0x000bc086 mono_handle_native_sigsegv + 422 1 mono-sgen
0x0000466e mono_sigsegv_signal_handler + 334 2 libsystem_c.dylib
0x913c659b _sigtramp + 43 3
0xffffffff 0x0 + 4294967295 4 mono-sgen
0x0020306d mono_gc_alloc_obj_nolock + 363 5 mono-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 mono-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 mono-sgen
0x0008c617 mono_main + 8551 17 mono-sgen
0x00002606 start + 54 18??? 0x00000003 0x0 + 3Отладка информации из gdb:
/tmp/mono-gdb-commands.2aCwlD:1: Ошибка в файле команды sourced: не удалось для отладки self
Получил SIGSEGV во время выполнения собственного кода. Это обычно указывает на смертельный ошибка в моно исполняемой версии или одна из встроенных библиотек, используемых вашей приложение.
/Users/fraser/Documents/diff-match-patch/csharp/GCtest.command: line 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");
}
}