WinForms App - Simulate Memory Usage and Programmatically Trim Working Set

Hi All,

I'm trying to create a demo Windows Forms App that does the following:

- Increases the memory working set of the application.
- Programmatically trims the working set.

I have 2 buttons on the form, 1 simulates managed memory usage and the other 1 simulates unmanaged memory usage. I'm not sure if this is the way to increase the working set (the amount of memory you see in Task Manager), but I've started writing it like that (see code example). If you have another way please let me know.

Basically, in my way:
- I'm trying to simulate memory usage (Private Bytes increases as well as Working Set increases).
- Release Private Bytes (via GC or any other way).
- The working set should remain the same (i.e. - even though the memory (private bytes) was released, Task Manager still shows a big chunk of memory reserved for the application).
- At this point, minimizing the application's main window dramatically decreases the working set. I'm trying to programmatically trim the working set by using the "SetProcessWorkingSetSize" function.

My goal is to create the demo application to show a customer, and I think I've got most of it handled. Just need some help with a few parts:

- I can increase Private Bytes and Working Set, but can't decrease the private bytes.
- I still have to try the SetProcessWorkingSetSize piece of code.

Here are some references:
http://arnosoftwaredev.blogspot.com/2007/10/how-to-trim-net-applications-memory.html
http://www.itwriting.com/dotnetmem.php

Thanks.
Dave
Imports System.Runtime.InteropServices
Imports System

Public Class Form1

    Private objBrushes As List(Of Brush) = New List(Of Brush)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim i As Integer
        For i = 0 To 2000
            Marshal.AllocHGlobal(7000)
        Next

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim i As Integer
        For i = 0 To 10000
            Dim obj As Brush = New SolidBrush(Color.Blue)
            objBrushes.Add(obj)
        Next

    End Sub
End Class

Open in new window

LVL 4
DangerizAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CodeCruiserCommented:
You may be able to increase the size but decrease is done automatically by garbage collector and apps can not control it.
0
DangerizAuthor Commented:
So I may have to take a different approach then.
How can I simulate a Windows App taking up Working Set in the Task Manager when the app loads and then when I minimize the form, then see the Working Set drop considerably?
In the real environment, data is read from a database with a datareader and then loaded into a dataset. There is quite a lot of data, and after the datareader is closed the memory is still allocated to the working set.
0
CodeCruiserCommented:
DataReader does not take a lot of memory as it only reads one line at a time. Its the Dataset which takes memory because it keeps all the data in memory. If you are loading data into dataset, why use a datareader? Use a DataAdapter.

Call Dispose function on all objects and set the object = nothing so that the GC releases the memory. It wont be instantaneous though.
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

DangerizAuthor Commented:
The customer says that they use the DataReader for faster access. They have quite a lot of data.

I disposed all the objects (all DataSets because I can't dispose DataReaders) and set them all to nothing, but the Working Set still hogs that much memory. I even closed all the forms in debug mode and had the application still open. Looks like the application still hogs the working set, even though all the objects in the application are close/disposed and set to nothing. This means that the private bytes (in perfmon) have decreased, but the working set (in Task Manager) doesn't decrease. That's why I have to use the "SetProcessWorkingSetSize" to force the trimming of the working set.
0
DangerizAuthor Commented:
The customer says that they use the DataReader for faster access. They have quite a lot of data.

I disposed all the objects (all DataSets because I can't dispose DataReaders) and set them all to nothing, but the Working Set still hogs that much memory. I even closed all the forms in debug mode and had the application still open. Looks like the application still hogs the working set, even though all the objects in the application are close/disposed and set to nothing. This means that the private bytes (in perfmon) have decreased, but the working set (in Task Manager) doesn't decrease. That's why I have to use the "SetProcessWorkingSetSize" to force the trimming of the working set.
0
CodeCruiserCommented:
>The customer says that they use the DataReader for faster access.
But if they are using the datareader to load a dataset then its doing them more harm than good. I would also suggest to use the stored procedures.

Regarding mem usage, as i said earlier, the code and all its environment is controlled by the CLR and CLR allocates and releases memory as and when it deems right.
0
DangerizAuthor Commented:
I am in agreement with you for using a SqlDataAdapter to fill the DataSet if they are ultimately loading the data into a DataSet anyway. I have already suggested that to the customer, but they don't want to change that as of now, since they don't see that being the problem.

This is the customer's problem:
They have a Windows Application that reads a massive amount of data with a couple of DataReaders that loads the data into the same DataSet. This happens only once on form load and the memory usage seen in Task Manager (working set) jumps to 180 MB for the application. On minimizing the main form, the working set reduces to about 20 MB thoughout the whole lifetime of the application.

Therefore, only the initial loading of the data causes the working set to jump that high. The customer is concerned that the 180 MB will cause problems with other applications on the server by hogging that much memory. So they want to programmatically release/trim the working set after the initial data load.
0
CodeCruiserCommented:
>On minimizing the main form, the working set reduces to about 20 MB

If you maximize the form again, does the mem go up again? If yes then some UI controls such as a grid may be taking the memory.
0
DangerizAuthor Commented:
No, on maximizing the form the application still stays around 20MB.
That's why the customer think's the easiest way to resolve this problem is to programmatically trim the working set with the "SetProcessWorkingSetSize" piece of code.

I think I'm just gonna write out that piece of code now. I just wanted to simulate the usage of working set so that I can test if the "SetProcessWorkingSetSize" works or not.
0
DangerizAuthor Commented:
Hey CodeCruiser,

Thanks for all your replies and effort.

I've actually used the example from this link:
http://www.vbforums.com/showthread.php?t=320745

And have managed to decrease the working set. Even though I still couldn't simulate memory usage like I wanted to. I wanted to make my app use up memory, then release the Working Set when I minimized the form. But the memory just stayed there when I minimized the form. I decided not to worry about simulating that, because the code from the above link seems to decrease both the Private Bytes and the Working Set.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
CodeCruiserCommented:
Good to hear that you managed to get it sorted :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.