Solved

string object not being release

Posted on 2010-11-29
19
329 Views
Last Modified: 2012-05-10
Hello
This is probably a stupid question but how can I release the memory without calling gc.collect()
The code bellow uses  800MB of memory when we click on button1, button2 doesn't seem to release anything, event after 5 minutes, (in release compilation)

Public Class Form1
    Dim l() As String
    Dim s = 10000

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim i
        ReDim l(s)
        l(0) = "fkdnm"
        For i = 1 To s - 1
            l(i) = l(i - 1) & "fkdnmvgd"
        Next
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim i
        For i = 0 To s - 1
            l(i) = ""
            l(i) = Nothing
        Next
        l = Nothing
        'GC.Collect(2)
    End Sub
End Class

Yes, I know I should use stringbuilder
Thanks

Louis
0
Comment
Question by:Atomica
  • 8
  • 4
  • 3
  • +2
19 Comments
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 34230582
How are you determining that it isn't releasing the memory? Also calling the GC from ASP.Net is generally a bad idea.
0
 

Author Comment

by:Atomica
ID: 34230612
Well task manager reports 800MB for this process when button1 is clicked, drops next to nothing as soon as gc.collect is called
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 34230688
Ah, ok. You've fallen into the classic trap of thinking that Task Manager is actually showing you how much memory is being used....it isn't, it is showing the Working Set, which isn't the same thing.

If you want to see a more accurate memory usage figure then you need to be looking at the Virtual Memory column in Task Manager or at the process\private bytes and process\virtual bytes in performance monitor.
0
 

Author Comment

by:Atomica
ID: 34230859
Ok, I included

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        MsgBox("VM:" & System.Diagnostics.Process.GetCurrentProcess.PrivateMemorySize64 / 1024 / 1024 & vbNewLine & "PM:" & System.Diagnostics.Process.GetCurrentProcess.PrivateMemorySize64 / 1024 / 1024)
    End Sub

Which shows used memory (GB)
But then again, no change when I click on button2
0
 

Author Comment

by:Atomica
ID: 34230867
BTW, I'm using CLR 2.0 in windows 2003 SBS
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 34230885
The memory is not automatically reclaimed by the .Net framework. running GC.Collect uses resources and it is only run when memory is required by the OS.

in your button 2, if you have only this, you can see that most memory is freed:
        l = Nothing
        GC.Collect()
0
 

Author Comment

by:Atomica
ID: 34231092
Ok so if were to saturate my memory with another process, the gc would reclaim the memory. I will try that and let you know.

Is the gc smart enought to release objects with circular references to each others?
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 34231345
>>Ok so if were to saturate my memory with another process, the gc would reclaim the memory. I will try that and let you know.

yes.

>>Is the gc smart enought to release objects with circular references to each others?

yes.
0
 

Author Comment

by:Atomica
ID: 34231477
I started  this sample application about 7 times, until my os started paging memory on disk

The initial process still shows 1.2GB of used VM

of course, if I start gc.collect, then the memory is release, any hypothesis?
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 69

Expert Comment

by:Éric Moreau
ID: 34231888
because Windows does not really shows what is in memory, what has been cached to disk, ... you cannot really follow it. Windows itself determines when it should put memory pressure (and then call gc.collect).

your job is to release your objects as soon as you can and let Windows manage what's left.
0
 

Author Comment

by:Atomica
ID: 34232174
But how can I make windows release the memory, I know its ease as putting l=nothing but Id like to see the memory used by the process go down without calling gc.collect
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 34232356
you have to call gc.collect.

Windows postpone this operation the further it can because it can be a costly operation.
0
 
LVL 18

Accepted Solution

by:
deighton earned 500 total points
ID: 34237650
do you know about the different generations of memory in .net?  

data starts off at generation zero, if it falls out of use then there are many level 0 garbage collections to reclaim that memory, if it is still in use it is promoted to level 1 garbage - level 1 garbage collection occurs less often.  Items surviving level 1 garbage collection go to level 2.  

Longest lived items end up as level 2 garbage, level 2 garbage collection occurs least often.  

I would recommend running performance monitor and looking at the .net CLR memory counters, look at the size of the heaps and the numbers of garbage collections occurring.

In your case you are generating a large array of increasingly large strings (as testing I guess).  The effect of this increased memory hit is probably to trigger first level 0 garbage collection, and very likely level 1 garbage collection.  Since your array object is still live during your loop, it very likely ends up as level 2 garbage.  Level 2 garbage is longer lived, you can't collect it without waiting for, or inducing, a level 2 garbage collection.  

.net tunes itself to decide when to call garbage collection.  Microsoft does not recommend inducing garbage collection, it can be detrimental to performance by affecting performance tuning parameters.

Note that when a system is under high memory usage, level 2 garbage collection frequency should increase.  

When I have tried experiments like yours, I often notice that a second execution of the test code triggers the garbage from the previous run to be collected.

Are you experiencing problems with out of memory exceptions, or are you just keen to 'clean up'.  If the latter, then leave .net to do that, do not make a problem if you do not have on.  Saying that I researched this stuff because we had memory problems!










0
 
LVL 18

Expert Comment

by:deighton
ID: 34237666
BTW, setting objects to nothing is now considered obsolete in .net - it too can be counter productive.  Your array goes out of scope when the page events are finished, and that alone is enough to render it collectable.

I agree though that the object=nothing was needed in your case before gc.collect, in that case.   Generally do not set objects to nothing, check that scope is no more than necessary and call dispose methods where provides, or create disposable objects with 'USING'
0
 

Author Comment

by:Atomica
ID: 34269425
Deigthon, what you said is very interesting, I indeed have a out of memory in my webapplication, Im using large shared datasets
I my logic, I do set outdated object to nothing, but the gc doesn't seem to reclaim them except when calling gc.collect, I dont want to use gc.collect as everyone is calling it the "devil"

Their is probably more than on source of problems in my code, but understanding when the GC is called is the my first objective and why I did this sample application.
In IIS 6, the application just restarted when out of memory exception occured, but in IIS7, it sometimes freezes completely without restarting

No so long ago, my search was to target event handler that would hold object in memory but now with gc.collect collecting, I will think of something else

I my test, I started 6 or 7 instance of the sample application, I can't believe that CLR would start paging memory on disk instead of calling gc.collect, as if disk paging was more efficient than calling gc.collect

I will look into using "using"
0
 
LVL 18

Assisted Solution

by:deighton
deighton earned 500 total points
ID: 34281627
Dataset memory is not reclaimed until the garbage collector does it for you.
Other than gc.collect, I believe there is no other way to speed dataset memory reclaim.  

Have you examined the CLR performance counters?  how much cached data do you have?  Does the amount of memory taken by the managed heaps dip when a level 2 garbage collection occurs or is induced with gc.collect.  Have you checked that there are not live references to objects you no longer need, because these can keep them alive.

Maybe you are caching too much data - are you holding them in the system cache.  Is this to avoid database retrieval overheads?  Is the data global between users, or is it specific to users.  Cached dataset are expensive in memory I have found.

If you can access data using a datareader instead of a dataset, or use SQL to reduce the size of the datasets, that can cut application server memory hit.

0
 

Author Comment

by:Atomica
ID: 34303466
when I call gc.collect, it collects almost everything but my question remains, why is gc.collect not collecting, my object are not live since they disapear when manually calling gc.collect, I find it strange the CLR starts paging or calling a "out memory excpetion" instead of freing up memory.

Apart from timing, is there a difference between calling gc.collect(2) manually and the CLR calling it for you?
0
 
LVL 29

Expert Comment

by:Kumaraswamy R
ID: 34479020
This question has been classified as abandoned and is being closed as part of the Cleanup Program.  See my comment at the end of the question for more details.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

This article discusses the ASP.NET AJAX ModalPopupExtender control. In this article we will show how to use the ModalPopupExtender control, how to display/show/call the ASP.NET AJAX ModalPopupExtender control from javascript, how to show/display/cal…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now