all groups > dotnet clr > april 2005 >
You're in the

dotnet clr

group:

Gc Mystery


Gc Mystery saurabhgarg2k NO[at]SPAM gmail.com
4/13/2005 2:25:56 AM
dotnet clr:
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
Re: Gc Mystery David Browne
4/13/2005 6:54:32 AM

[quoted text, click to view]

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

Re: Gc Mystery saurabhgarg2k NO[at]SPAM gmail.com
4/13/2005 9:59:39 AM
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
Re: Gc Mystery clyon NO[at]SPAM online.microsoft.com (
4/13/2005 6:06:23 PM
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
RE: Gc Mystery Ravichandran J.V.
4/14/2005 12:42:39 AM
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.


[quoted text, click to view]
Re: Gc Mystery Phil Wilson
4/14/2005 5:30:18 PM
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.
--
Phil Wilson [MVP Windows Installer]
----
[quoted text, click to view]

Re: Gc Mystery saurabhgarg2k NO[at]SPAM gmail.com
4/15/2005 4:53:55 AM
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
AddThis Social Bookmark Button