Laden...

OutOfMemory obwohl Arbeitsspeicher frei

Erstellt von elturco vor 11 Jahren Letzter Beitrag vor 11 Jahren 3.410 Views
E
elturco Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren
OutOfMemory obwohl Arbeitsspeicher frei

Hallo erstmal,

ich hab ein Problem, und zwar versuche ich eine 400MB-große Datei in meine C#-Applikation einzulesen.
Nach einer Weile bekomme ich eine OutOfMemoryException. Anschließend habe ich eine Zeile hinzugefügt, die ausgibt, wieviel Arbeitsspeicher noch frei ist.
Zu dem Zeitpunkt, wo die Exception ausgelöst wird, habe ich noch 7 GB Arbeitsspeicher frei.

Meine Frage; wieso kommt es zu einer OutOfMemoryException?

Viele Grüße

F
10.010 Beiträge seit 2004
vor 11 Jahren

Wenn du den Speicher ausliest nachdem das Programm bereits mit der Exception beendet wurde, zeigt dir dein Rechner nicht mehr an wie viel speicher verbraucht war.

Auch kann ein Programm u.U. nicht den ganzen freien Speicher benutzen.
Ist es z.b. wegen COM als 32Bit Anwendung compiliert, kann es nicht mal 4GB benutzen.
Auch wird eine OOM Exception z.b. auch bei einigen GDI Operationen geworfen.

Und natürlich kannst Du auch sehr leicht durch falsche Stringprogrammierung aus 400MB locker zig GB an Daten erzeugen.

E
elturco Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren

Erstmal vielen Dank...

zu 1. Ich lese den Speicher nach jeder Zeile, zu Anfang waren es 8GB, bei der letzten, die eingelesen wird, ist es noch 7GB.

zu 2. Es ist eine 32-Bit-Anwendung, aber laut 1. verbraucht sie bislang nur 1GB.

zu 3. Bei welchen z.B.?

zu 4. Kann ich das irgendwie feststellen?

4.939 Beiträge seit 2008
vor 11 Jahren

Schau dir doch einfach den StackTrace bei der Exception an, dann siehst du doch welche Methode die OutOfMemoryException wirft. Und wenn sie von der CLR geworfen wird, dann hast du wohl wirklich ein Speicherproblem (und bei einem 32bit-Programm auf einem 64bit-System mit mehr als 4 GB ist nicht der verfügbare Arbeitsspeicher ausschlaggebend, sondern der prozessbezogene Speicher, der max. 4 GB sein kann).

2.891 Beiträge seit 2004
vor 11 Jahren

wieso kommt es zu einer OutOfMemoryException?

Die tritt auch gern auf, wenn man eine Endlosrekursion erzeugt hat.
Also - wie schon empfohlen - die Exception abfangen und mal in den StackTrace gucken.

5.658 Beiträge seit 2006
vor 11 Jahren

wieso kommt es zu einer OutOfMemoryException?
Die tritt auch gern auf, wenn man eine Endlosrekursion erzeugt hat.

Dann ist es aber eine StackOverflowException.

Christian

Weeks of programming can save you hours of planning

2.891 Beiträge seit 2004
vor 11 Jahren

Dann ist es aber eine StackOverflowException.

Kommt drauf an - kann auch eine OutOfMemoryException sein. Kannste mir glauben, hatte ich neulich erst auf dem Tisch. 😉

E
elturco Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren

Laut StackTrace ist die letzte aufgerufene Methode "DevExpress.Xpf.LayoutControl.LayoutGroup.GetInternalElements()"...

2.891 Beiträge seit 2004
vor 11 Jahren

Laut StackTrace ist die letzte aufgerufene Methode "DevExpress.Xpf.LayoutControl.LayoutGroup.GetInternalElements()"...

Und die Methoden davor?
Kann auch sein, dass die DevExpress-Komponente einen Fehler hat. Guck dir mal [Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden an und mach ggf. eine Supportanfrage bei DX auf.

E
elturco Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren

Fehlermeldung:
bei DevExpress.Xpf.LayoutControl.LayoutGroup.GetInternalElements()
bei DevExpress.Xpf.Core.PanelBase.IsInternalElement(UIElement element)
bei DevExpress.Xpf.Core.PanelBase.GetChildren(Boolean includeInternalElements, Boolean includeTempChildren, Boolean visibleOnly)
bei DevExpress.Xpf.Core.PanelBase.GetLogicalChildren(Boolean visibleOnly)
bei DevExpress.Xpf.Core.PanelBase.CheckChildChanges()
bei DevExpress.Xpf.Core.PanelBase.OnLayoutUpdated()
bei DevExpress.Xpf.Core.PanelBase.<AttachToEvents>b__17(Object , EventArgs )
bei System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
bei System.Windows.ContextLayoutManager.UpdateLayout()
bei System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
bei System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
bei System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
bei System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
bei System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
bei MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
bei System.Windows.Threading.DispatcherOperation.InvokeImpl()
bei System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
bei System.Threading.ExecutionContext.runTryCode(Object userData)
bei System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Windows.Threading.DispatcherOperation.Invoke()
bei System.Windows.Threading.Dispatcher.ProcessQueue()
bei System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
bei MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
bei MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
bei MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
bei System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
bei MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
bei MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
bei System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
bei System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
bei System.Windows.Application.RunDispatcher(Object ignore)
bei System.Windows.Application.RunInternal(Window window)
bei System.Windows.Application.Run(Window window)
bei System.Windows.Application.Run()
bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
bei System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
bei System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
bei System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
bei System.Activator.CreateInstance(ActivationContext activationContext)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()

5.658 Beiträge seit 2006
vor 11 Jahren

Hi elturco,

und in welcher Methode lädst du deine 400-MB-Datei?

Christian

Weeks of programming can save you hours of planning

E
elturco Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren

Die Methode ist hier nicht aufgelistet. Sie heißt "getDataFromFile"...

Naja, immerhin vielen Dank. Anscheinend werde ich das nicht hinbekommen...

5.941 Beiträge seit 2005
vor 11 Jahren

Hallo elturco

Wird die Datei denn überhaupt geladen?
Kannst du es auch mal mit einer kleineren probieren?

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

E
elturco Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren

Ja mit kleineren funktioniert es. Bei der größeren Datei werden ca. 300.000 Zeilen von 500.000 eingelesen.

16.835 Beiträge seit 2008
vor 11 Jahren

Zeig doch, wie bereits darum gebeten, wie Du Deine Datei lädst.
Wenn Du nur eine Referenz auf das Laden erzeugst und erst in der DX Komponente eine Materialisierung durchgeführt wird, dann ist das schon mal ein Hinweis. Würdest Du die Materialisierung durchführen, dann würde womöglich das gleiche passieren.

Diesbezüglich kann es aber durchaus der Fall sein, dass es einfach (durch schlechte Programmierung, unglückliches Design oder was auch immer) von DX so nicht vorgesehen und unterstützt wird.
300.000 Daten bilden auch ein Volumen, dass sowieso nicht direkt vom Menschen erfasst werden kann.
Da muss man sich schon eher fragen, ob das sinn macht und ob man nicht vielleicht dynamisch die einzelnen Bereich nachlädt / ersetzt.

Eine OutOfMemoryException kann durch viele Dinge geworfen werden.
Sei es allgemein, dass keine Ressourcen mehr zur Verfügung stehen (RAM, Handles....) oder auch integrierte Probleme, zB das vollständige Laden von riesigen Dateien in ein XML DOM.

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo elturco,

32bit Programme können nur 2GB Speicher benutzen, nicht 4GB.

Wenn du die Datei z.B. mit File.ReadAllText zusammenhängend in den Speicher lädst, wird ein zusammenhängender Speicherbereich 400MB benötigt. Der ist möglicherweise selbst dann nicht mehr frei, wenn in der Summe noch (wesentlich) mehr als 400MB frei ist (siehe auch large object heap). Wenn du die Datei dagegen mit File.ReadAllLines lesen würdest (und keine überlangen Zeilen enthalten sind und auch die Zeilenanzahl nicht übergroß ist), wären wesentlich kleinere Speicherhäppchen ausreichend.

Davon abgesehen kommt - wie auch Abt schon gesagt hat - eine OutOfMemoryException nicht nur, wenn eine Speicheranforderung an den Arbeitsspeicher nicht erfüllt werden kann, sondern auch wenn andere Speicherbereiche erschöpft sind, z.B. der für die Handles für Controls.

herbivore