Laden...

CreateViewStream in MonoDevelop, Exception wenn der Datenstrom zu oft erzeugt wird

Erstellt von schirmi87 vor 9 Jahren Letzter Beitrag vor 8 Jahren 1.699 Views
S
schirmi87 Themenstarter:in
13 Beiträge seit 2010
vor 9 Jahren
CreateViewStream in MonoDevelop, Exception wenn der Datenstrom zu oft erzeugt wird

Hi Leute,

ich habe ein Problem mit dem Verwenden von CreateViewStream mit Mono unter Linux.
Und zwar möchte ich ein Textfile einlesen (ca. 21MegaByte) und über CreateViewStream einen Datenstrom dazu erzeugen da dieser später noch benötigt wird. Dieser muss auch komplett sein und darf nicht in Schnippseln sein deshalb wird er auch so angegeben:

MemoryMappedViewStream myMMFViewStream = mySequentialMMF.CreateViewStream (0, 0, MemoryMappedFileAccess.ReadWrite);

Das klappt auch alles ganz gut wenn die Datei ca. nur 2Mb groß ist aber wenn die Datei eine Größe von 21Mb hat bekomme ich folgende Exception> Fehlermeldung:

mmap failed for fd#4(0, 216600000)

Unter Windows bekomme ich keine Probleme nur unter Linux fliegt die Exception.
Ein Speicherproblem kann ich eigentlich ausschließen, da ich noch genügend freien Arbeits- und Festplattenspeicher zur Verfügung dafür habe. Hat jemand vielleicht einen Tipp woran das liegen könnte?.

Hier der Code von dem ganzen Konstrukt:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Reflection;

namespace PersistentMemoryMappedFile
{
    class Program
    {
        static string LargeString = "1111111111111111111111111111111111111111...1111111111111";
        static int Main()
        {
			string filename = "largetextfile.txt";
			//Hier wird das 20Mb große File erzeugt
            CreateLargeFile();
            CreateMemoryMappedFile(filename);

			return 0;

        }

		private static void CreateMemoryMappedFile(string fileName)
		{
				try {
					FileInfo fInfo = new FileInfo (fileName);
					long length = fInfo.Length;
					MemoryMappedFile mySequentialMMF = MemoryMappedFile.CreateFromFile (fileName, FileMode.Open, "MySequentialMap");
					for (long i = 0; i < length; i++) {
					//hier fliegt immer bei i=1016 oder i=1017 die Exception "mmap failed for fd#4(0, 21660000)"
						MemoryMappedViewStream myMMFViewStream = mySequentialMMF.CreateViewStream (0, 0, MemoryMappedFileAccess.ReadWrite);
						Console.WriteLine (i.ToString ());
					}
				} catch (Exception ex) {
					Console.WriteLine ("Exception geflogen!");
					System.Threading.Thread.Sleep (2000);
					string errormsg = ex.Message;
					Console.WriteLine (errormsg);
				}
		}

        private static void CreateLargeFile()
        {
			if (File.Exists ("largetextfile.txt"))
				File.Delete ("largetextfile.txt");
            using (StreamWriter sw = new StreamWriter("largetextfile.txt", false))
            {
                for (int i = 0; i < 10000; i++)
                    sw.WriteLine(LargeString);
            }

        }

    }
}


Vielen Dank schon einmal!
schirmi87

16.807 Beiträge seit 2008
vor 9 Jahren

Riecht danach, dass dies Mono noch nicht vollständig unterstützt.
Jedenfalls sind laut Github viele Elemente noch als ToDo markiert.

F
10.010 Beiträge seit 2004
vor 9 Jahren

Und warum gibt es diese Vorgabe überhaupt?

Wenn das eine Volltextsuche werden soll, würde ich das eher in eine SQLite DB schmeissen, die gibt es auch unter Linux.

Und per FTS4 geht das sehr performant.

U
1.688 Beiträge seit 2007
vor 9 Jahren

Muss der erzeugte "ViewStream" tatsächlich nicht aufgeräumt werden (Dispose, using)?

S
schirmi87 Themenstarter:in
13 Beiträge seit 2010
vor 8 Jahren

Vielen Dank für eure Antworten!
Das blöde ist allerdings, das ich es nur unter Windows mit Dispose oder GC.Collect() aufräumen kann.
Also so:


                for (long i = 0; i < length; i++)
                {
                    //hier fliegt immer bei i=1016 oder i=1017 die Exception "mmap failed for fd#4(0, 21660000)"
                    MemoryMappedViewStream myMMFViewStream = mySequentialMMF.CreateViewStream(0, 0, MemoryMappedFileAccess.ReadWrite);
                    //long totalMemory = GC.GetTotalMemory(false) / 1024;
                    Console.WriteLine(i.ToString());
                    myMMFViewStream.Dispose();
                   


                }

oder mit


GC.Collect();

den Speicher wieder freigeben!

Habt ihr vielleicht noch eine Idee wie man unter Mono seinen Speicher noch aufräumen kann. Ich finde leider nirgends noch jemanden der ein ähnliches Problem unter Mono hat wie ich!

Danke euch
schirmi87

16.807 Beiträge seit 2008
vor 8 Jahren

Beantworte doch mal FZelles frage und sag, was das werden soll.
Evtl. kann man dann ne andere Lösung anbieten...

S
schirmi87 Themenstarter:in
13 Beiträge seit 2010
vor 8 Jahren

Sorry für die viel zu späte Antwort!
Es war dafür vorgesehen, dass eine große Anzahl von Dateien eingelesen werden sollte.
Das Problem liegt an Mono und konnte ich bisher noch nicht behoben werden.
Ich habe es jetzt so gelöst, dass ich das Programm einfach neu starte, sobald ich die Exception einfange. Es ist zwar überhaupt nicht elegant aber löst mein Problem erstmal auf unbestimmte Zeit 😉
Ich werde demnächst nochmal die neuste Version von Mono testen. Eventuell wurde das in Mono intern gelöst.

Vielen Dank euch allen
schirmi87