Cóż, mono jest świetne, ale o ile widzę, jest niestabilne. Działa, ale powoduje błędy, gdy proces monofoniczny wymaga poważnej pracy.
TL; DR - Nie używaj mono, jeśli:
- użyj AppDomains (zestaw Load \ Unload) w środowiskach wielowątkowych
- Nie można utrzymać modelu „niech to zawiedzie”
- Od czasu do czasu doświadczaj dużych obciążeń podczas przebiegu procesu
Więc fakty.
Używamy mono-2.6.7 (.net v 3.5) na RHEL5, Ubuntu i, z mojego punktu widzenia, jest to najbardziej stabilna wersja zbudowana przez Novell. Ma problem z rozładowaniem AppDomains (segfaults), jednak zawiesza się bardzo rzadko i jest to zdecydowanie dopuszczalne (przez nas).
W porządku. Ale jeśli chcesz korzystać z funkcji .net 4.0, musisz przełączyć się do wersji 2.10.x lub 3.x i tam zaczynają się problemy.
W porównaniu z wersją 2.6.7 nowe wersje są po prostu niedopuszczalne. Napisałem prostą aplikację do testów warunków skrajnych do testowania instalacji mono.
Jest tutaj, z instrukcją użycia: https://github.com/head-thrash/stress_test_mono
Używa wątków roboczych puli wątków. Pracownik ładuje bibliotekę DLL do AppDomain i próbuje wykonać pracę matematyczną. Część pracy jest wielowątkowa, część pojedyncza. Prawie cała praca jest związana z procesorem, chociaż niektóre odczyty plików z dysku.
Wyniki nie są bardzo dobre. W rzeczywistości dla wersji 3.0.12:
- sgen GC segfaulty przetwarzają prawie natychmiast
- mono z boehmem żyje dłużej (od 2 do 5 godzin), ale w końcu segfault
Jak wspomniano powyżej, sgen gc po prostu nie działa (mono zbudowany ze źródła):
* Assertion: should not be reached at sgen-scan-object.h:111
Stacktrace:
Native stacktrace:
mono() [0x4ab0ad]
/lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0) [0x2b61ea830cb0]
/lib/x86_64-linux-gnu/libc.so.6(gsignal+0x35) [0x2b61eaa74425]
/lib/x86_64-linux-gnu/libc.so.6(abort+0x17b) [0x2b61eaa77b8b]
mono() [0x62b49d]
mono() [0x62b5d6]
mono() [0x5d4f84]
mono() [0x5cb0af]
mono() [0x5cb2cc]
mono() [0x5cccfd]
mono() [0x5cd944]
mono() [0x5d12b6]
mono(mono_gc_collect+0x28) [0x5d16f8]
mono(mono_domain_finalize+0x7c) [0x59fb1c]
mono() [0x596ef0]
mono() [0x616f13]
mono() [0x626ee0]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a) [0x2b61ea828e9a]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d) [0x2b61eab31ccd]
Jeśli chodzi o boehm segfauls - na przykład (Ubuntu 13.04, mono zbudowany ze źródła):
mono: mini-amd64.c:492: amd64_patch: Assertion `0' failed.
Stacktrace:
at <unknown> <0xffffffff>
at System.Collections.Generic.Dictionary`2.Init (int,System.Collections.Generic.IEqualityComparer`1<TKey>) [0x00012] in /home/bkmz/my/mono/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:264
at System.Collections.Generic.Dictionary`2..ctor () [0x00006] in /home/bkmz/my/mono/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:222
at System.Security.Cryptography.CryptoConfig/CryptoHandler..ctor (System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) [0x00014] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/Crypto
Config.cs:582
at System.Security.Cryptography.CryptoConfig.LoadConfig (string,System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) [0x00013] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoCo
nfig.cs:473
at System.Security.Cryptography.CryptoConfig.Initialize () [0x00697] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:457
at System.Security.Cryptography.CryptoConfig.CreateFromName (string,object[]) [0x00027] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:495
at System.Security.Cryptography.CryptoConfig.CreateFromName (string) [0x00000] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:484
at System.Security.Cryptography.RandomNumberGenerator.Create (string) [0x00000] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:59
at System.Security.Cryptography.RandomNumberGenerator.Create () [0x00000] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:53
at System.Guid.NewGuid () [0x0001e] in /home/bkmz/my/mono/mcs/class/corlib/System/Guid.cs:492
Lub (RHEL5, mono jest pobierane z rpm tutaj ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/home%3A/vmas%3A/mono-centos5 )
Assertion at mini.c:3783, condition `code' not met
Stacktrace:
at <unknown> <0xffffffff>
at System.IO.StreamReader.ReadBuffer () [0x00012] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.IO/StreamReader.cs:394
at System.IO.StreamReader.Peek () [0x00006] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.IO/StreamReader.cs:429
at Mono.Xml.SmallXmlParser.Peek () [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/Mono.Xml/SmallXmlParser.cs:271
at Mono.Xml.SmallXmlParser.Parse (System.IO.TextReader,Mono.Xml.SmallXmlParser/IContentHandler) [0x00020] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/Mono.Xml/SmallXmlParser.cs:346
at System.Security.Cryptography.CryptoConfig.LoadConfig (string,System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) [0x00021] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptog
raphy/CryptoConfig.cs:475
at System.Security.Cryptography.CryptoConfig.Initialize () [0x00697] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:457
at System.Security.Cryptography.CryptoConfig.CreateFromName (string,object[]) [0x00027] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:495
at System.Security.Cryptography.CryptoConfig.CreateFromName (string) [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:484
at System.Security.Cryptography.RandomNumberGenerator.Create (string) [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:59
at System.Security.Cryptography.RandomNumberGenerator.Create () [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:53
at System.Guid.NewGuid () [0x0001e] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System/Guid.cs:483
at System.Runtime.Remoting.RemotingServices.NewUri () [0x00020] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs:356
at System.Runtime.Remoting.RemotingServices.Marshal (System.MarshalByRefObject,string,System.Type) [0x000ba] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs:329
at System.AppDomain.GetMarshalledDomainObjRef () [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System/AppDomain.cs:1363
Obie awarie są w jakiś sposób powiązane z logiką AppDomains, więc powinieneś trzymać się od nich z daleka w mono.
BTW, testowany program pracował bez żadnych problemów 24 godziny na komputerze z systemem Windows w MS .NET 4.5 env.
Podsumowując, chciałbym powiedzieć - ostrożnie używaj mono. Działa od pierwszego spojrzenia, ale może łatwo zawieść za każdym razem. Pozostanie ci kilka podstawowych zrzutów i poważna utrata wiary w projekty typu open source.