WPF Memory Usage #2 - wpf

I've asked a question about my memory management problem in WPF, but this is a different one about the same problem.
I am using DotTrace trying to figure out what's going on. When I start up my app, I can see in Task Manager that it is taking 200MB. DotTrace says a total of 33MB. If I simply minimize the window and bring it back up, the memory footprint according to TM is about 25MB.
I have a ListBox that shows peoples names and pictures. It shows up to 3000 people (I will work on paging, but that's not the point here). As I scroll down, I can see in TM that the memory increases rapidly. If I just keep scrolling up and down memory quick gets to 1GB. During the scroll there are no changes to the underlying data and there are no events of my own. If I minimize the window and bring it back up, memory drops from 1GB to 25MB.
Before minimizing and seeing the memory go down in TM I took a snapshot with DotTrace and it shows the same amount of memory as before the scrolling - around 30MB or so.
Can someone please explain to me what happens to memory when the app is minimized? Is the figure shown in Task Manager to be trusted?
Thanks
PS1:
There's no change in behavior if I do or don't add this to my ListBox:
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
PS2:
I've put a button with the code, and the GC doesn't reclaim much if anything(it drops from, say 700MB to 680MB):
GC.Collect();
GC.WaitForPendingFinalizers();

Can't give you a definitive answer, but some things to point out:
DotTrace only shows managed memory usage. It looks your app is using large amounts of unmanaged memory (possibly allocated by WPF itself for all those images).
Minimizing a process doesn't generally free any memory, it just pages it out so it can be used by other applications. It's a red herring in this case.
Look into how .Net's generational garbage collection works.
Until your process reaches the resource limits set by the OS it will not necessarily release any memory it has allocated to it.
Use the Performance Counters built into Windows. They will show you a more useful overall breakdown of your app's memory than DotTrace, including managed and unmanaged memory.
DotTrace sucks. Get ANTS or something. I love ReSharper, but Jetbrains really shouldn't charge for DotTrace, it's woeful.
Edit: 4) is a bit misleading - .Net's memory manager can release memory for other reasons (when a generation is full, for starters).

If you are using a Virtualizing container, the visual objects will be created dynamically as you scroll around. This will in turn could cause a bit of havok with the GC since you are creating rather chunky objects very quickly. Once you minimize, I would assume that the GC is kicking in and collecting all those visual objects.
EDIT:
After seeing your edit, you might want to try setting the IsVirtualizing to false for testing. The default value is true, so omitting it would not change anything.

Related

Tracking down memory leak in Google App Engine Golang application?

I saw this Python question: App Engine Deferred: Tracking Down Memory Leaks
... Similarly, I've run into this dreaded error:
Exceeded soft private memory limit of 128 MB with 128 MB after servicing 384 requests total
...
After handling this request, the process that handled this request was found to be using too much memory and was terminated. This is likely to cause a new process to be used for the next request to your application. If you see this message frequently, you may have a memory leak in your application.
According to that other question, it could be that the "instance class" is too small to run this application, but before increasing it I want to be sure.
After checking through the application I can't see anything obvious as to where a leak might be (for example, unclosed buffers, etc.) ... and so whatever it is it's got to be a very small but perhaps common mistake.
Because this is running on GAE, I can't really profile it locally very easily as far as I know as that's the runtime environment. Might anyone have a suggestion as to how to proceed and ensure that memory is being recycled properly? — I'm sort of new to Go but I've enjoyed working with it so far.
For a starting point, you might be able to try pprof.WriteHeapProfile. It'll write to any Writer, including an http.ResponseWriter, so you can write a view that checks for some auth and gives you a heap profile. An annoying thing about that is that it's really tracking allocations, not what remains allocated after GC. So in a sense it's telling you what's RAM-hungry, but doesn't target leaks specifically.
The standard expvar package can expose some JSON including memstats, which tells you about GCs and the number allocs and frees of particular sizes of allocation (example). If there's a leak you could use allocs-frees to get a sense of whether it's large allocs or small that are growing over time, but that's not very fine-grained.
Finally, there's a function to dump the current state of the heap, but I'm not sure it works in GAE and it seems to be kind of rarely used.
Note that, to keep GC work down, Go processes grow to be about twice as large as their actual live data as part of normal steady-state operation. (The exact % it grows before GC depends on runtime.GOGC, which people sometimes increase to save collector work in exchange for using more memory.) A (very old) thread suggests App Engine processes regulate GC like any other, though they could have tweaked it since 2011. Anyhow, if you're allocating slowly (good for you!) you should expect slow process growth; it's just that usage should drop back down again after each collection cycle.
A possible approach to check if your app has indeed a memory leak is to upgrade temporarily the instance class and check the memory usage pattern (in the developer console on the Instances page select the Memory Usage view for the respective module version).
If the pattern eventually levels out and the instance no longer restarts then indeed your instance class was too low. Done :)
If the usage pattern keeps growing (with a rate proportional with the app's activity) then indeed you have a memory leak. During this exercise you might be able to also narrow the search area - if you manage to correlate the graph growth areas with certain activities of the app.
Even if there is a leak, using a higher instance class should increase the time between the instance restarts, maybe even making them tolerable (comparable with the automatic shutdown of dynamically managed instances, for example). Which would allow putting the memory leak investigation on the back burner and focusing on more pressing matters, if that's of interest to you. One could look at such restarts as an instance refresh/self-cleaning "feature" :)

High unmanaged Memory - WPF Application

I'm about to deploy my new WPF application and I've just noticed in the Task Manager that it was consuming a lot of memory. So I downloaded a trial of RedGate Antz to try and find out what was causing this issue and I was shocked to see about 90 MB of unmanaged memory usage. Because Antz does not support unmamaged memory I then tried to use Windbg which did not point to a high usage itself. This leads me to believe it must be one of the DLLs I'm loading. I'm using the DevExpress controls in my application.
An interesting feature is when I minimize my application the memory drops right down from say 110 MB to about 6-10 MB.
Should I be concerned / worried?
This is my first WPF application and I'm not totally sure what to expect in terms of memory usage. Does the fact when minimized this memory is regained/given up a sign that everything is ok?
Any thoughts or ideas on what could be causing this would be most helpful.
I've had good luck with SciTech's .Net Memory Profiler (memprofiler.com) if you want to know specifically what's causing it.
With the nature of the .Net runtime, if you're running on a machine that has plenty of memory available then it will generally try to use it. If you start seeing performance problems related to it then you should worry, and generally it's good to be aware of what is using resources regardless. A probable reason for the drop in memory is one of the DLLs may hook to your main Window's events and invoke a garbage collection on minimize.
If you're concerned about the perception of high memory usage there are tricks you can play to massage the numbers that show up in TaskManager (like p/invoking SetProcessWorkingSetSize), but that doesn't seem to be really what you're asking about.

WPF Performance issue with Unmanaged objects

I have developed an application in WPF with C#. The application includes a third party dll for displaying the camera in a particular window.
Normally the application takes the memory 90 MB - 135 MB without camera object (Unmanaged object). i.e I removed all the code reagrding the camera object in the design and code page (xaml and xaml.cs). The memory increasing and stops at one max value.
If I use the camera object in the application, the memory is increasing gradually. When I open the camera window every time, the memory will be increased gradually like 135 MB 141 MB, 143 MB....
I have used GC.Collect and the Using statement for all necessary place to clear the managed memory. I am not able to reduce or stop the memory increasing.
How to solve this issue?
Any suggestions will appreciate
Thanks in advance.
Using GC.Collect typically doesn't reduce your memory footprint. Stop calling that and you may see some improvement.
On a more general note, you shouldn't worry so much about the perceived footprint of your .NET application (especially if you're monitoring it through Task Manager!). The .NET runtime will release memory when it needs to - for example when under pressure, or when idle - and so the value you're seeing isn't necessarily indication that it's using more memory - it's just reserved memory for the time being.
One small test that can demonstrate this: what happens when you minimise your .NET app? Very often you'll see memory use in Task Manager drop dramatically, and it won't come back up immediately when you redisplay the window.
It seems you have answered your own question:
If I use the camera object in the application, the memory is
increasing gradually. When I open the camera window every time, the
memory will be increased gradually like 135 MB 141 MB, 143 MB....
I have used GC.Collect and the Using statement for all necessary place
to clear the managed memory. I am not able to reduce or stop the
memory increasing.
As stated above, GC.Collect only perform garbage collecting on managed objects, NOT unmanaged object. I assume the memory leaks comes from the camera object you used, not from the managed code. Then why bother you blame GC.Collect for high memory rises?
This is why I assumed the blame on the camera object:
Normally the application takes the memory 90 MB - 135 MB without
camera object (Unmanaged object). i.e I removed all the code reagrding
the camera object in the design and code page (xaml and xaml.cs). The
memory increasing and stops at one max value.
If I use the camera object in the application, the memory is
increasing gradually. When I open the camera window every time, the
memory will be increased gradually like 135 MB 141 MB, 143 MB....
Then you should investigate the camera control you used. It's obvious, the culprit is the camera control.
Does the unmanaged camera component have a C# wrapper? If so does it implement IDisposable? Ensuring you dispose the camera object (if wrapped) will call its destructors in unmanaged code
Is the unmanaged code connected to your C# code via DLL import? If so ensure you are calling all "Close()" type methods to free memory in C#. I would advocate wrapping the camera component in your own .NET class implementing IDisposable in order to neatly package this up
Are you subscribing to any .NET events and not unsubscribing? Such as Camera.ImageReceived += new EventHandler...
Leaving subscriptions to .NET events open can cause a subtle memory leak as the GC cannot collect an object while there is a reference to it (via event subscription)
Finally, a crude test to check for memory leak would be to leave your app running overnight with multiple create / delete camera window operations. See if you get an OutOfMemoryException the next day. As previous posters mentioned Task Manager is not going to report accurately the memory usage of a .NET app, however the acid test is does the GC eventually free the memory or does it keep growing indefinitely?

WPF finding resource and memory leaks

Does anyone have some suggestions for issolating resource and/or memory leaks in a WPF application?
I have verified that there does appears to be some significant leaks in our application through the monitoring of heap sizes in Task Manager while using the application. I did download the evaluation of the Memory Profiler tool, played with it for an hour or so and moved on. Now my evaluation period has expired. While using it many issues were reported, but I had not invested the time to wade through all of the verbose report.
What is the best tool for this? Should I invest the time and money on Memory Profiler or go with something else. I used to use BoundsChecker in C++ and it was great, slowed down the application a lot but pinpointed right where you had an issue.
I would like a tool to identify the source of our leaks.
Any .net memory profiling tool would do. For WPF specific memory profiling we used http://msdn.microsoft.com/en-us/library/aa969767.aspx.
But we could also do better memory profiling of our WPF application using WinDbg .... even SOS helps. You just need to have a way to understand its commands.

Wpf Animation performance drops suddenly

I have a simple fade in animation on a large Rectangle inside a ScrollViewer and I notice a significant drop in performance when I increase my windows size past a certain size.
resolution: 1650x1256 - still feels snappy and fluent (framerate between 50 and 60)
resolution: 1820x1256 - stutters and is pretty much unusable (framerate between 7 and 15)
What surprises me is that there doesn't seem to be a linear decline in performance but a rather sudden drop.
Also using Wpf Performance Tool does NOT show any software rendering and indeed my CPU doesn't seem to be doing much when the animation runs.
I would like to understand the cause of this, any hints would be appreciated.
Another possibility is that you are running out of dedicated video memory at that resolution, so DirectX is transferring a lot of data back and forth between video memory and main system memory on every frame.
Is there any way you can try a different graphics card, or one with more RAM, to see if the problem changes?
Also, does your GPU have a way to configure how much system RAM is reserved as video memory? Some do.
My guess is that you are running out of GPU memory at that point, so DirectX is dropping back to software rendering.
When you say a "viewport", do you mean a ViewPort3D, or do you mean a Viewbox? If it is a Viewport3D, is the animation really needing the 3D processing? If not, you could use 2D and use a transform to simulate 3D the way Flash applications have to do.

Resources