Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / April 2005

Tip: Looking for answers? Try searching our database.

Gc Mystery

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
saurabhgarg2k@gmail.com - 13 Apr 2005 10:25 GMT
Hi there guys,

Here is the code snippet which in which i am trying to read a file and
taking two cases in first one i promote the object to Gen1 so that it
will be saved from frequent Gen0 Collections and dont have to read file
again which is a costly business.In second case, normal process without
promoting.So trying to prove that first case works faster

Module Module1
   Sub main()
       Dim objTest1 As New Test1
       Dim someNumber As Integer = 500
       Dim i As Integer
       Dim t As DateTime
       Dim CurrentTime As DateTime

       t = DateTime.Now
       For i = 0 To 100000
           objTest1.ReadFile()
       Next

       CurrentTime = DateTime.Now
       Console.WriteLine(String.Format("Time taken with promotion:
{0}:{1}", CurrentTime.Subtract(t).Seconds,
CurrentTime.Subtract(t).Milliseconds))
       Console.WriteLine("File Read: {0} times",
TextFile._fileReadCount)
       TextFile._fileReadCount = 0

       Dim objTest2 As Test1 = New Test1
       t = DateTime.Now
       For i = 0 To 100000
           If (i Mod someNumber = 0 AndAlso i > 0) Then
               GC.Collect(0)
           End If
           objTest2.ReadFileWithoutPromotion()
       Next

       CurrentTime = DateTime.Now
       Console.WriteLine(String.Format("Time taken without promotion:
{0}:{1}", CurrentTime.Subtract(t).Seconds,
CurrentTime.Subtract(t).Milliseconds))

       Console.WriteLine("File Read: {0} times",
TextFile._fileReadCount)
       TextFile._fileReadCount = Nothing
       GC.Collect()
       GC.WaitForPendingFinalizers()
       Console.ReadLine()
   End Sub
End Module

Class TextFile
   Public ReadOnly Filename As String
   Private wrText As WeakReference
   Public Shared _fileReadCount As Integer = 0

   Public Sub New(ByVal filename As String)
       Me.Filename = filename
   End Sub

   Public ReadOnly Property Contents() As String
       Get
           Dim txt As String
           If Not (wrText Is Nothing) Then
               ' if the weakly referenced string is
               ' still there, return it to caller
               txt = DirectCast(wrText.Target, String)
               If Not (txt Is Nothing) Then _
                  Return txt
           End If
           ' else we need to read (again) the file
           Dim sr As System.IO.StreamReader
           Try
               _fileReadCount += 1
               ' read the entire file in one shot
               sr = New System.IO.StreamReader(Filename)
               txt = sr.ReadToEnd()
               ' create a weak-reference to it
               ' and return to main app
               wrText = New WeakReference(txt)
               Return txt
           Finally
               ' close the stream if necessary
               If Not (sr Is Nothing) Then _
                  sr.Close()
           End Try
       End Get
   End Property
End Class

Public Class Test1
   Dim objText As New TextFile("C:\Log.txt")
   Private _flag As Boolean = False

   Public Sub ReadFile()
       Dim t As String = objText.Contents
       If GC.GetGeneration(t) = 0 Then
           GC.Collect(0)
           Console.WriteLine("File Contents Promoted to Next
Generation")
       End If
   End Sub

   Public Sub ReadFileWithoutPromotion()
       Dim t As String = objText.Contents
   End Sub
End Class

Problem:
For my utter surprise in the First iteration of first for loop when it
goes into Contents property and after reading the File, the generation
of the variable "txt" is 2.I cant solve this mystery.Can any1 pick out
what is happening.

Thanks and Regards
Saurabh Garg
David Browne - 13 Apr 2005 12:54 GMT
> Hi there guys,
>
[quoted text clipped - 110 lines]
> of the variable "txt" is 2.I cant solve this mystery.Can any1 pick out
> what is happening.

No mystery.  If the generation of txt is 2, then it has survived a Gen0
collection and a Gen1 collection, or it's a large object.  This single line:

txt = sr.ReadToEnd()

might cause multiple collections, or any other line for that matter.  BTW
it's slightly bad form to put so much code in a property.  Using a function
instead warns the client that there may be non-trivial processing inside.

David
saurabhgarg2k@gmail.com - 13 Apr 2005 17:59 GMT
Thanks for the reply,

By saying multiple collections there, u mean to say that as soon as
Gen0 is full,GC(0) gets fired and if it cud not find enough space in
Gen0 for the new object , it wud fire GC(1), and subsequently GC(2)

wud these GCs be considered as seperate GCs and the objects surviving
that wud be promoted 1 Gen each, is that the case.

Or wat is the process if u want to elaborate.

and will the Finalizers get fired in Gen0 and Gen1 collection too or
only after Gen2 and Large Object Heap has been collected.

FYI the file size which i am trying to load is 35.5 KB and i presume
Large objects eligibility criteria is way high than that.

Looking forward for the reply

Thanks and Regards
Saurabh Garg
"Chris Lyon [MSFT]" - 13 Apr 2005 19:06 GMT
Hi Saurabh

I highly recommend you read these articles on how the GC works.  Some of
the details are out of date, but the general idea is correct:
http://msdn.microsoft.com/msdnmag/issues/1100/gci/
http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/

To answer your specific questions:

| By saying multiple collections there, u mean to say that as soon as
| Gen0 is full,GC(0) gets fired and if it cud not find enough space in
| Gen0 for the new object , it wud fire GC(1), and subsequently GC(2)

That's correct (although greatly simplified).

| wud these GCs be considered as seperate GCs and the objects surviving
| that wud be promoted 1 Gen each, is that the case.

Yes.

| and will the Finalizers get fired in Gen0 and Gen1 collection too or
| only after Gen2 and Large Object Heap has been collected.

Finalizers get called by the finalizer thread at some undetermined point
after the object is collected, regardless of the generation they came from.

| FYI the file size which i am trying to load is 35.5 KB and i presume
| Large objects eligibility criteria is way high than that.

Yes, Large Objects are > 85kb

Hope that helps
-Chris
Ravichandran J.V. - 14 Apr 2005 08:42 GMT
By default, whenever a collection occurs on a generation, objects in the
current generation will be promoted to a higher generation. This is what is
happening in your case. Use a Performance Counter of the .Net CLR Memory type
that will help you monitor the collections performed in a generation.

with regards,

J.V.

> Hi there guys,
>
[quoted text clipped - 113 lines]
> Thanks and Regards
> Saurabh Garg
Phil Wilson - 15 Apr 2005 01:30 GMT
Isn't this what GC.KeepAlive is for?  Well you could argue that it isn't,
but adding a KeepAlive (on what he wants to stop getting collected) at the
end of his main would stop them being collected and it's cleaner than doing
those Collect calls etc.
Signature

Phil Wilson [MVP Windows Installer]
----

> Hi there guys,
>
[quoted text clipped - 113 lines]
> Thanks and Regards
> Saurabh Garg
saurabhgarg2k@gmail.com - 15 Apr 2005 12:53 GMT
A question arises again which refers to the code sample in my first
posting, as David says

txt = sr.ReadToEnd() ' File size 35.5 KB

This Single line can cause GC to run,alright, but why the GC will run
at this line , i presume because it cudnt find enough space for the
object to allocate, so it triggers GC(0) and then GC(1) and if still no
space a Full GC and in the meantime all the objects belong to Gen0
which could not be deallocated wud be promoted to Gen1 and all the
objects from Gen1 to Gen2, so eventually there are no objects belong to
Gen0.

and the code line which trigger GC has not been allocated yet because
the GC has been triggered just because it cudnt find enough space for
it.So how can an object survives two Generations although it still
hasnt been allocated yet.

or is it the case that runtime has allocated the object and then runs
the GC but then again i have checked the Generation of "txt" without
executing another line of code so there is no other object allocation
which could possibly fire GC.

So wats the mess,i hope u will understand the point i am trying to make
here.

Thanks and Regards
Saurabh Garg

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.