What could cause this memory issue? - c#

I'm working on an app for windows phone 8, and I'm having a memory leak problem. But first some background. The app works (unfortunately) using WebBrowsers as pages. The pages are pretty complex with a lot of javascript involved.
The native part of the app, written in c#, is responsible for doing some simple communication with the javascript(e.g. native is a delegate for the javascript to communicate with a server), make animation for page transition, tracking, persistance, etc. All is done in a unique PhoneApplicationPage.
After I had some crashes for out of memory exceptions, I started profiling the app. I can see that the WebBrowsers, which are the big part of the the app, are being disposed correctly.
But the problem I'm seeing is that memory continues to increase. What's worse, I have little feedback from the profiler. From what I understand, the profiler graph says there is a big problem, while the profiler numbers say there's no problem at all...
Note: the step represents a navigation from a WebBrowser to another WebBrowser. The spike is created (I suppose) by the animation between the two controls. In the span I've selected in the image, I was doing a navigation forward and one backward having a maxium of 5 WebBrowsers (2 for menus that are always there, 1 for the index page, 1 for the page I navigate from and 1 for the page I navigate to). At every navigation the profiler shows the correct number of WebBrowsers: 5 after navigating forward, 4 after navigating backward.
Note 2: I have added the red line to make clearer that the memory is going up in that span of time
As you can see from the image
the memory usage is pretty big but the numbers say it's low and in that span of time, retained allocation is lower than when it started...
I hope I've included enough information. I want some ideas on what could cause this problem. My ideas so far are:
-the javascript in the WebBrowser is doing something wrong (e.g. not cleaning some event handler). Even if this is the case, shouldn't the WebBrowser release the memory when it is destroyed?
-using a unique PhoneApplicationPage is something evil that is not supposed to be done, and changing its structure may cause this.
-other?
Another question: why does the graph show the correct amount of memory use while the number doesn't?
If you need more info about the profiler, ask and I will post them tomorrow.

Ok after a lot of investigation I finally was able to find the leak.
the leak is created by the WebBrowser control itself which seems to have some event handler that are not removed when you remove it from a Panel. In fact the leak is reproducible by following these steps:
Create a new WebBrowser
Add it to a Panel or whatever
Navigate to a page, with an image which is big and heavy
Tap somewhere in the blank space of the browser(tapping on the image seems to not create the leak)
remove and collect the browser
repeat from 1
at every iteration the memory of the image is never collected and the memory continue to grow.
A ticket to Microsoft was already sent.
The problem was resolved using a pool of WebBrowsers

I don't think There is enough information to find the cause to your leak, and without posting your entire solution I am not sure there can be, since the question is about locating the root cause of it...
What I Can offer is the approach I have used when I had my own memory leak.
The technique was to:
Open a memory profiler. From your screenshot I see you are using one. I used perfmon. This article has some material about setting perfmon and #fmunkert also explains it rather well.
Locate an area in the code that you suspect that it is likely that the leak is in that area. This part is mostly depending on you having good guesses about the part of the code that is responsible for the issue.
Push the Leak to the extreme: Use labels and "goto" for isolating an area / function and repeat the suspicious code many times (a loop will work to. I find goto more convenient for this matter).
In the loop I have used a breakpoint that halted every 50 hits for examining the delta in the memory usage. Of course you can change the value to feet a noticeable leak change in your application.
If you have located the area that causes the leak, the memory usage should rapidly spike. If the Memory usage does not spike, repeat stages 1-4 with another area of code that you suspect being the root cause. If it does, continue to 6.
In the area you have found to be the cause, use same technique (goto + labels) to zoom in and isolate smaller parts of the area until you find the source of the leak.
Note that the down sides of this method are:
If you are allocating an object in the loop, it's disposal should be also contained in the loop.
If you have more than one source of leak, It makes it harder to spot (yet still possible)

Did you clean up your event handlers? You may inadvertently still have some references if the controls are rooted.

Related

UWP application is getting slow after usage of some time?

I have developed one UWP application.In that nearly 20 windows are there.
Every window contains lot of Xaml controls. For some time it's working fine.
But after usage of some time application is getting very slow.
After doing some R&D I came to know that it's called Memory Leakage.
As per my knowledge in .Net Garbage Collector has to take care of this if I am not wrong.It seems like In UWP Application it is not happening. So I thought I should use GC.Collect() in Page Unload Event.
Is that correct approach or anything else I need to do to release memory which are used by the window controls?
The performance optimization is a vast subject and may not be possible to answer on an open ended question (without knowledge of your environment and architecture etc).
However you can use the Visual Studio profiler to measure and track performance and to find out the area where you need to take action, these can be;
Data binding
UI Virtualization
Image rendering
Visual Tree Size
Further reading these urls may also help you.
ms docs and this blog
The GC takes care of orphaned objects or objects that are no longer referenced by any other classes. when the GC finds objects like these it removes them from memory. memory leaks happen when an object is referenced by another class even after it is done with it. this means you need to look at your code and find where this is happening. you need to help GC in doing its job by making sure you no longer reference objects you don't need.
I also wouldn't recommend using GC.Collect in page unload event since GC has to freeze threads in order to collect. this might impact performance.

OutOfMemory Exception when debugging

I'm running a very small program that throws "System.OutOfMemoryException" when there's clearly a lot of memory available:
Under the task manager, I got plenty of memory left, and the process is taking around 45MB.
Is there a way to increase this process memory limit?
EDIT1:
I moved some code around, and this made the error get triggered in many different spots. The latest, after loading a form and filling it with data from the database, I just change from one tab to another in a TabControl and that triggers the exception.
I'm using Entity Framework 6 and a Postgres database, if that helps. Maybe the framework is creating too many instances of objects and I'm running out of memory indexes.
That's why I think the code itself is not relevant to the question.
EDIT2:
I took another screenshot of the memory analyser before and after the exception occurs:
So the problem is that I'm getting over 100K objects in memory, and I'm not having enough memory pages to create new ones? I'm still quite lost on how to handle this.
EDIT3:
Well, I found the culprit of the memory leak: Entify Framework. The memory consumption increase happens after I first load data from the database. Now I'll have to properly debug if the problem is in the Postgre driver or on Entity Framework itself. Will have to test with a different database to check.
Here's two screenshots showing the difference before and after I use EF. The code loads some items in two comboboxes, both using the same List as a datasource. On the first example. I have EF, on the second I loaded the same types of objects, but creating them myself, no connection to the database. The difference is astonishing!
EDIT 4:
Well, this is embarassing. I moved to a different solution. Now I'm working with Simple.Migration to manage changes in the database, and Dapper (with Dapper.Contrib) to handle CRUD. Hope they see this and maybe see what's going wrong...
Memory usage can be different from memory reserved. The system can reserve memory (it says "I have dibs on that megabyte") but not actually utilize it. I'm not certain whether Visual Studio shows the memory usage or reserved, but you can check it through Task Manager, going to the Performance tab, and clicking the Resource Monitor button near the bottom of the window. The Memory tab in the Resource Monitor window will show how much memmory is commited.
If you have this problem, and I bet you do, then you are repeatedly declaring something and not instantiating or deleting it, or you are adding endless objects to a list. It's most likely happening inside a loop. It is very unlikely that Visual Studio is hitting a memory limit, unless your computer is a potato.

Memory consumption keeps growing when just moving the mouse [duplicate]

This question already has answers here:
.NET WinForm Memory Consumption
(3 answers)
Closed 9 years ago.
Today I've discovered by myself a strange thing experimenting things about the memory consumption, I can't find any documentation of this anywhere, but sure all developer experts knows about of what I want to talk here.
The thing is... When you compile a default WinForms in VB or also C#, when you move the mouse over the form, that action causes to increase the memory consumption to about 8-16 kb per second...
The most important thing is that memory will never be collected/freed!
So the longer you move the mouse over the form, the more RAM consumption will be generated and never will come down, thereby possibly causing an StackOverFlow error, and that's the main reason of my preoccupation...
I have a WinForms application where it needs to stay running over hours and the mouse need to be moved over the app from one point to another each second, so I need to perform a way to avoid this strange memory consumption problem which can produce itself an stackoverflow error.
I've tested the same thing in a Java application and the thing goes dramatical!, if you move the mouse over an empty window then you can see how the memory consumption increases MB0s per second! ...instead the few KB's per second like in VB/C#, and like in VB/C# Form that memory never goes down, there's no way back, it's True what the people says about Java and the memory consumption of that language...I think it sucks.
Then to make the same test on another language I've chosen C++ 'cause is the other one important, I don't have any C/C++ IDE to compile so what I did is to choose some official programs I have made in C/C++ like for example "Winamp" and this time the result is... DOES NOT HAPPENS ANYTHING WHEN MOVING THE MOUSE OVER THE C/C++ APPS! The memory consumption does not increase, absolutely Zero increase.
I've made this experiment with a default Windows Forms application (Empty Form1.vb Class), in C# and in VB, but I work only with VB. I've used .Net Framework 4.0 and 4.5. In Windows 8 x64.
Some expert developer can help me to understand all of this paranormal things?
· Why the memory goes up between 8-16 kb each second when moving the mouse in a VB/C# WinForm.
· Why that increase of memory never goes down again?
· Why the same problem does not happens in C/C++ apps?
(I can understand C++ does not have the same engine (Framework) but anyways... I don't know if that's the reason.)
And the most important question...
· I can prevent that memory increase when moving the mouse over the form?, maybe overriding some native methods or...I don't know...exist a way to avoid it?
UPDATE:
The way how I've measured the memory consumption is just simply as seeying the memory in TaskManager.exe
The reason why I said "The memory never be collected" is because when moving the mouse over the form, the memory counter does not go down on taskmanager, never.
UPDATE 2
I uploaded a video explaining the problem, you can see it with your own eyes! ...I'm not crazy.
http://www.youtube.com/watch?v=sBxicL_x9HQ&feature=youtu.be
Why the memory goes up between 8-16 kb each second when moving the mouse in a VB/C# WinForm.
There are messages that trigger for handling mouse movement, etc, which get processed by the form.
Why that increase of memory never goes down again?
It will. Eventually, you'll see your memory settle down. In C# and VB.Net, the garbage collector doesn't immediately clean up memory (by design), but lets it grow, and will clean up as needed. In general, you'll tend to see .NET applications grow in their memory usage, then drop dramatically, then grow again, then drop, etc. If you have a lot of memory in your system, the "drops" happen infrequently, since a garbage collection is expensive, and there's absolutely no disadvantage to using memory that's not needed elsewhere.

Help finding a leak with Remote Performance Monitor

I'm trying to find the source of a memory leak in a Compact Framework application using the Remote Performance Monitor. I managed to remove a few minor ones related to brushes and other graphic objects, but I still don't have a clear idea of what is causing the main problem.
At this point the only objects that seem to never go back to their original count are System.String objects. I find this to be very weird, since I would've thought that in order for these objects to remain uncollected, the objects that contain them would have to remain as well, and yet no other type of objects seem to be increasing along with the System.Strings.
I'm trying to find out which new String objects are the ones that remain after the application returns to its original state (i.e. the login screen). The problem is that originally, the application loads with about 2200 string objects, and then after process "X" it increases another 70 or so which never get collected. I don't know how to identify those 70 new objects, in order to find out who is holding on to them and make the appropriate corrections.
Does anyone have any experience in which Strings were not being collected? Is there any way to separate the new objects created during process "X" from those that were originally required by the application so that I can know which are leaking? Any advice would be appreciated.
Thanks
**UPDATE
Ok... there is something very strange going on. I'm starting to doubt whether there is a leak at all.
Let's say that I take a memory snapshot at the Login screen which is the original starting point of the application. Imagine that there are 1000 string objects in memory at this point. Now, if I login and choose an option from the menu, I'll take a snapshot once the new screen is loaded. Let's say that loading this form increases the string count by say 50 objects. When I logout and take a snapshot again at the login screen, only 25 of those objects have been collected, the rest will stay in memory from then on.
The strange thing is that if I keep repeating this process, no further string objects will accumulate. Instead of the string count increasing by 50, only 25 will be added at this point, and those same 25 will be collected once I go back to the login screen. I'm thinking that if this were an actual leak, then each time that I opened that screen the string count would increase permanently by 25, but this only happens the first time.
This happens to me on every new screen that I open. At first there is a small permanent increase in the overall string count, but once I've loaded that particular screen, any increase in the string count during its execution will be collected once I go back to the login screen.
All of this has led me to believe that perhaps those strings are part of the inner workings of the CLR or something like that. Could it be some sort of caching done by the runtime? Perhaps it is storing my string constants for faster loading? Something like that? I hope this wasn't too confusing.
if you're using CF 3.5, then use the CLR Profiler instead of RPM. It will show you all objects and the roots that spawned them. It would allow you to walk back the root tree to figure out where they were allocated.
EDIT
So you're saying that you aren't actually getting OOMs or any aberrent behavior? Sounds like you're trying to optimise when it's not necessary. Those string are likely things like Form captions, etc. that the JITter is creating and would get collected if/when the objects get collected. What they are, though, really isn't terribly important if you're not actually seeing memory problems.

System.OutOfMemory being thrown. How to find the culprit?

I am using Visual C# Express 2008 and I have an application that starts up on a form, but uses a thread with a delegated display function to take care of essentially all the processing. That way my form doesn't lock up while tasks are being processed.
Semi-recently, after going through a repeated process a number of times (the program processes incoming data, so when data comes in, the process repeats) my app will crash with a System.OutOfMemory error.
The stack trace in the error message is useless because it only directs me to the the line where I call the delegated form control function.
I've heard people say they use ProcMon from SysInternals to see why errors like this happen. But I, for the life of me, can't figure it out. The amount of memory I am using doesn't change as the program runs, if it goes up, it comes back down. Plus, even if it was going up, how do I figure out which part of my program is the problem?
How can I go about investigating this problem?
EDIT:
So, after delving further into this issue, I looked through anything that I was ever re-declaring. There were a few instances where I had hugematrix = new uint[gigantic], so I got rid of about 3 of those.
Instead of getting rid of the error, it is now far more obscured and confusing.
My application takes the incoming data, and renders it using OpenGL. Now, instead of throwing "System.OutOfMemory" it simply does not render anything with OpenGL.
The only difference in my code is that I do not make new matrices for holding the data I plot. That way, I hope, my array stays in the same place in memory and doesn't do anything suicidal to my LOH.
Unfortunately, this twists the beast far beyond my meager means. With zero errors popping up, and all my data structures apparently still properly filled, how can I find my problem? Does OpenGL use memory in an obscure way so as to not throw exceptions when it fails? Is memory still a problem? How do I find out? All the memory profilers in the world seem to tell me very little.
EDIT:
With the boatloads of support from this community (with extra kudos to Amissico) the error has finally been rooted out. Apparently I was adding items to an OpenGL list, and never taking them off the list.
The app that finally clued me in was .Net Memory Profiler. At the time of crash it showed 1.5GB of data in the <unknown> category. Through process of elimination (everything else in the list that was named), the last thing to be checked off the list was the OpenGL rendering pipleline. The rest is history.
Based on the description in your comments, I would suspect that you are either not disposing of your images correctly or that you have severe Large Object Heap fragmentation and, when trying to allocate for a new image, don't have enough contiguous space available. See this question for more info - Large Object Heap Fragmentation
You need to use a memory profiler, such as the ants memory profiler to find out what causes this error.
Are you re-registering an event handler on every loop and not un-registering it?
CLR Profiler for the .NET Framework 2.0 at https://github.com/MicrosoftArchive/clrprofiler
The most common cause of memory fragmentation is excessive string creation.
Following considerations:
Make sure that threads you spawn are destroyed (aborted or function return). Too much threads can fail application, although in Task Manager used memory is not too high
Memory leaks. Yes, yes, you can cause them in .net pretty well without setting reference to nulls. This can be solved by using memory profilers like dotTrace or ANTS Memory Profiler
I had an OutOfMemoryException-problem as well:
Microsoft Visual C# 2008 Reducing number of loaded dlls
The reason was fragmentation of 2GB GB virtual address space and poster nobugz suggested Sysinternal's Vmmap utility which has been very helpful for diagnostics. You can use it to check if your free memory areas become more fragmented over time. (First sort by size then by type -> refresh repeat sorting and you can see if contiguous free memory blocks become smaller)

Categories