WindowsCodecs adding memory footprint of WPF application - wpf

I downloaded Red gate ANTS Memory Profiler and profiled my app. I noticed that my app had a lot of unmanaged memory allocated (160MB). So I ran the profiler again with unmanaged memory profiling enabled. The break down of the unmanaged memory as follows:
WindowsCodecs: 45.19MB
CLR: 43.21MB
Allocated by Managed code: 30.23MB
Allocated before profiling started: 2.047MB
d3d9: 595.5KB
Other modules: 67.27MB
Other modules also contains the red gate memory profiler which accounted for 64.94MB of the 67.27MB.
From reading the Red Gate documentation, loading the CLR is expected to be around 40MB and my managed code allocating 30MB seems reasonable. But I am confused by the WindowsCodecs taking up 45MB! I am assuming that WindowsCodex is related to video codecs or playback. My app does not use Windows Media Player media control nor does it do any media playback of any sort (audio or video).
Anybody run into this? It appears my app could get a 45MB memory footprint reduction if I can figure out what is pulling in this dependency.

Related

WPF Performance - GPU overhead/usage plummets when Visual Studio GPU profiler attached?

So I have a WPF application which contains lots of real time effects - drawing directly to bitmaps, shader effects, etc. - and it all works great.
However, GPU usage is a bit higher than I would like, It hovers around 20%. I during the process of optimising, I tried attaching the Visual Studio profiler. When this is attached, and GPU Usage is selected as one of the profiling tools, when my WPF application runs....... the same app, with the same content....... GPU usage hovers around 5%!!!
After a heck of a lot of messing around, it does indeed seem that yes, when the profiler is attached (specifically GPU Usage, doesn't happen e.g. with just CPU usage selected) then yes the GPU usage plummets.
Please note the following (and I reference 5% and 20% as being if the profiler is attached or not)
I monitored GPU usage in task manager, and cross checked in Windows Performance Monitor/perfmon with the gpu are showing the same thing, I do not believe it is being misreported
You can look at system power monitoring and physically see more power being used under higher load level
If pushed my applications content, you can visually see in certain cases that at 5%, things run a bit smoother than at 20% (less frame drops), though in general...
Frame rate at both 20% and 5% usage is same 60fps
Happens if run directly in visual studio as debug, release, optimisation on or not, whatever
Happens if published and run stand alone
You can attach visual studio at run time with it's profiler (GPU tool) - starting and stopping the profiler literally toggles between 5% and 20% usage when you do it - no restarting my App or anything
Profiling everything in detail using visual studio, jetbrains dotTrace etc. does not identify any noticeable differences in the running app during 5% and 20% usage. E.g. jetbrains output showing call trees, time spent processing, call rates, etc. - 5% and 20% produce the same outputs.
Good old WPF Performance Suite/wpfperf shows no difference between 20% and 5% usage of number of calls being made etc. (though the visual profiler doesn't seem to work with latest .net core unfortunately)
GPU profiling is not showing any difference in VS
Nvidia CUDA toolkit - well it didn't want to work trying to profile this. Nor did RenderDoc - so did look at those.
I can scale the usage of gfx used in my app up and down, to vary the 20%/5%, but there is always a difference between profiler attached or not
Playing with the windows timer, just in case - Windows low level system timer resolution running at a consistant 1ms for both 20% and 5% - and confirmed no other known power saving settings are being changed. This was confirmed both at run time, and variants where I manually set things in code.
My app is a .net core 3.1 app. GFX is an nvidia GTX 2060s.
Of note, I have seen similar before in a separate WPF app (lots of 3D inside it, running .net 4.x framework) - where running the gpu profiler as above would make the 3D rendering run more smoothly. Tested on different pc's with different GFX hardware. It is also the same across different versions of GFX drivers.
Absolutely stumped what might be causing this.... I wouldn't mind if it was the other way around and was 4 times faster when no profiler was attached!
I am aware that when profiling, various things might get set in the background. I would have no clue at all what these might be.
Does anyone have any ideas at all?
Many thanks
Martin
Extra:
I found something similar, which is when the debugger is not attached in visual studio then performance is better - but my case here doesn't require any debugger, and appears to be GPU profiler specific, so don't believe it is anything like that. Why does my program run way faster when I enable profiling?
Example screenshot of performance on system demonstrating this...
High usage = no profiler attached. When everything drops, the profiler is attached and running (from around 15-38 seconds). Big red arrows = my task. Note there is other activity going on, including visual studio starting up the profiler, detatching it, etc.
Example project (source + built) you can see this happening...
https://1drv.ms/u/s!As6cQRoZ5gU5x8FzXdwcYS1qEFqjdg?e=98o64j
...note this is a new WPF project, created 15 minutes ago independently of my original project, with a test 3d object loaded into it - and also shows a performance difference - almost 50% less on my pc when visual studio gpu profiler attached

The memory usage shown in memory profiler is different from Process Explorer

I'm learning to use .Net Memory Profiler and testing the memory usage of Microsoft's DataBindingLab sample project.
.Net Memory Profiler shows total live bytes are 2011015, ie. 2MB.
Process Explorer shows Private Bytes are 56MB.
Obviously, there is such a big difference between the value given by the two tools. Where does the remaining 54MB come from?

Memory usage profiled in task manager and memory profiler tools

.Net winform application.
I used several memory profiler, including CLR profiler, DotTrace memory, Net memory profiler.
The tools gave the result that the allocated memory was 38-40M. But I found that working set was 300-400M in task manager(almost the same size as Peak working set or memory or commit size.
So what's the difference between the two results? What do the results mean?
those tools may show you private bytes or managed heap size, this does not include, e.g. memory mapped file, either page file backed or disk file backed, your app may be r/w ing
big mapped file, so working set looks big, or your app just load too many dll/assemblies.
VMMAP (from sysinternals) can give a clear overview of memory type/size in your app.

Finding the true memory footprint of a Windows application

I've run into a few OutOfMemoryExceptions with my C#/WPF application and I'm running into some confusing data while attempting to profile the memory usage.
When the app is typically running, Windows Task Manager shows the memory usage as somewhere around 34 MB (bounces around slightly as objects are created and garbage collected). When I run memory profiling applications such as CLR Profiler and dotTrace Memory, they show the total memory usage at around 1.2 MB.
Why this huge discrepancy? What does Task Manager see that these profilers do not?
UPDATE: I added some diag code to my application to print out various memory information every so often via the Process class.
While running my app, I set up a rule in DebugDiag to perform a memory dump in the event of an exception. I forced an exception and the memory dump occurred. At this point, the memory usage of my app (as shown by task manager) jumped from 32 MB to 145 MB and remained there.
You can see this jump in the table below (WorkingSet64). I'm still trying to make sense of all the types of memory info provided by the Process class. How would an external application make the working set of my app grow like this?
Link to data table here.
Using some of the diagnostics tools suggested here, plus the ANTS memory profiler (which is so money) I found the source of the leak.
WPF Storyboard animations leak under .NET 3.5
The WPF BitmapEffect class can cause leaks. The alternative "Effect" class fixes the leak. Link, Link
XAML Merged ResourceDictionaries can cause leak. Link, Link
The "Working Set" memory footprint of an application (memory shown by task manager) is not a good indication of your process' footprint. Outside applications can influence this. Link
The memory profiling tools helped me find that the leaks were mostly in unmanaged code, which made it a real pain to track down. Dealing with these leaks, plus a better understanding of Windows memory (private vs working set) cleared things up.
Prcess Explorer and VMMap, both part of the Sysinternals Suite by Mark Russinovich.

Performance issues running WPF/Win32 Applications Side by Side?

We have an old (Win32) and new (WPF) version of our blotter software, which the traders are currently running side by side. However, running the WPF application often severly slows down the redraw rate of the Win32 application.
Without the WPF application running (or minimized), draw rate is fluid and fast in the Win32 application. With the WPF application open alongside it, the Win32 appl's UI draw rate slows down noticeably. Running the WPF application seems to trigger use of some resources which are taken away from the Win32 app (both graphics-heavy) - causing the slow down it seems.
CPU and Memory are not anywhere near being saturated, so it doesn't seem to be related to those. Lowering resolution and/or reducing the number of monitors to display on (therefore decreasing video card memory usage and bandwidth load) makes no noticeable difference, therefore it doesn't seem to be a graphics hardware performance issue either.
One hypothesis that may explain the cause is as follows:
Under the hood, we know that both the WPF and Win32 applications output graphics information to a windows "message pump" which is basically a queue of instructions of what to draw to the screen. It seems as if when the WPF application is not running, the Win32 has full unfettered access to this and screen updates are fluid. Running the WPF application alongside it puts additional messages on this queue, so Win32 application has to compete harder for access to it (in order to do each screen element update), therefore "clogging the pump" giving the effect we see.
If the above is the case, can anyone recommend approaches to manage/control the window message pump in order to prevent this happening?
The flicker is the type you typically get when resources run low, where you can see individual elements (forms, labels) flicker and gradually draw on to the screen.
If anyone has any suggestions/ideas, let us know.
Each process will have its own message pump - this is not shared.
If you are not seeing high CPU utilization, then WPF is using hardware rendering, so it could possibly be GPU saturation. Can you get information on GPU utilization?
The following post details methods of getting GPU utilization:
Programmatically fetch GPU utilization
Okay, I think we've found the cause, and fix. In a nutshell, hardware and software accelerated windows don't play nice. Using software-rendering across the board fixes glitches that were previously there when running hardware-accelerated windows. Since our legacy Win32 app will be decommissioned soon, this is a workable comprimise - we can simply switch hardware acceleration back on when we drop the legacy application.
Notes below:
It seems like this issue is being caused by running a traditional software-accelerated 2D application (X) and 3D hardware-accelerated WPF one (Y) at the same time, and is a graphics driver issue.
Forcing Y to run in WPF software-acceleration mode as well causes little degradation in scrolling performance (as the bottleneck is still the grid's internal layout code).
However, what it does do, is get rid of the slow drawing issue in X, because Y is now running as a software-accelerated 2D application, like all other Windows applications on trader's machines. This explains why no applications other than Y caused slowdown - it seems as if software and hardware-accelerated graphics applications don't play nice when run at the same time.
This makes sense - when I play a hardware-accelerated game, for instance, I've seen similar (where the desktop redraws very slowly when switching to/from the game between hardware/software acceleration modes).
Thankfully we can turn off hardware-rendering without much impact in performance. Once X is decommissioned we can switch hardware-acceleration back on for the minor benefits it provides in Y (support for smoother animations and heavier use of fill gradients without slowing down etc).

Resources