Die Community zu .NET und Classic VB.
Menü

VB.NET-Tipp 0096: Mit System.GC Informationen über die Garbage Collection erhalten

 von 

Beschreibung

Die .NET-Speicherverwaltung funktioniert über einen eine sog. Garbage Collection (GC) - zu deutsch Müllsammler oder Müllabfuhr. Unbenutzte Objekte werden automatisch freigegeben, allerdings weniger transparent als zum Beispiel bei referenzzählenden Systemen in VB6 verwendet. Die Objekte werden in verschieden Generationen gegliedert; langlebige Objekte wandern in höhere Generationen.

Mit der Klasse System.GC kann man diesen Mechanismus ansprechen (Aufräumen veranlassen) und Informationen abrufen, wie z.B. die Generation eines Objektes oder die Menge des allozierten Speichers. Dieser Tipp zeigt ein paar Funktionalitäten der Klasse und stellt in kleinen Zeitschritten aktualisiert Speicherverteilung und die eigene Generation graphisch dar.

Zusätzlich kann man auch ungenutzte Objekte erstellen (auch IDisposable, die gesondert behandelt werden) und sehen, wie der GC reagiert.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Framework-Version(en):

.NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5

.NET-Version(en):

Visual Basic 2005, Visual Basic 2008

Download:

Download des Beispielprojektes [12,7 KB]

' Dieser Quellcode stammt von http://www.activevb.de
' und kann frei verwendet werden. Für eventuelle Schäden
' wird nicht gehaftet.

' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
' Ansonsten viel Spaß und Erfolg mit diesem Source!

' Projektversion:   Visual Studio 2008
' Option Strict:    Aus
' Option Explicit:  An
' Option Infer:     An
'
' Referenzen: 
'  - System
'  - System.Data
'  - System.Deployment
'  - System.Drawing
'  - System.Windows.Forms
'  - System.Xml
'  - System.Core
'  - System.Xml.Linq
'  - System.Data.DataSetExtensions
'
' Imports: 
'  - Microsoft.VisualBasic
'  - System
'  - System.Collections
'  - System.Collections.Generic
'  - System.Data
'  - System.Drawing
'  - System.Diagnostics
'  - System.Windows.Forms
'  - System.Linq
'  - System.Xml.Linq
'

' ##############################################################################
' ################################# Form1.vb ###################################
' ##############################################################################
Public Class frmGC

    Const NumGenerations As Long = 3
    Const NumInstances As Long = 42 * 100

    Friend CurrentInstances As Long = 0

    Private FooList As New List(Of MyDisposable)

    Private Sub frmGC_Disposed(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles Me.Disposed

        For Each Item As IDisposable In FooList
            Item.Dispose()
        Next
    End Sub

    Private Sub frmGC_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load

        tmrUpdateGC.Enabled = True

        pNumGenerations.Maximum = NumGenerations
        pMyGeneration.Maximum = NumGenerations
    End Sub

    Private Sub tmrUpdate_Tick(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles tmrUpdateGC.Tick

        UpdateGCInformation()
    End Sub

    ' Das Herzstück des Programmes - GC-Informationen beziehen
    Sub UpdateGCInformation()

        ' Maximum-Generationenzahl
        Dim MaxGeneration As Integer = GC.MaxGeneration

        ' Generation des aktuellen Objekts (Me)
        Dim MyGeneration As Integer = GC.GetGeneration(Me)

        ' Gesamtzahl der allozierten Bytes
        Dim TotalMemory As Integer = GC.GetTotalMemory(False)

        ' Anzeigen setzen
        lblTotalMemory.Text = TotalMemory.ToString("000,000") & " Bytes"
        lblNumObjects.Text = CurrentInstances.ToString("000,000")
        lblNumGenerations.Text = MaxGeneration.ToString & " / " & NumGenerations
        lblMyGeneration.Text = MyGeneration.ToString & " / " & NumGenerations

        pMyGeneration.Value = MyGeneration
        pNumGenerations.Value = MaxGeneration

    End Sub

    Private Sub cmdAllocMemory_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles cmdAllocMemory.Click

        Dim Instance As MyInstance
        For i As Long = 1 To NumInstances
            Instance = New MyInstance(Me)
        Next
    End Sub

    Private Sub cmdCreateGargabe_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles cmdCreateGargabe.Click

        For i As Long = 1 To NumInstances
            FooList.Add(New MyDisposable(Me))
        Next
    End Sub

    Private Sub cmdDisposeGarbage_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles cmdDisposeGarbage.Click

        For i = 0 To FooList.Count - 1
            FooList(i).Dispose()
            FooList(i) = Nothing
        Next
        FooList.Clear()
    End Sub

    Private Sub cmdDoCollection_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles cmdDoCollection.Click

        GC.Collect(GC.MaxGeneration)
    End Sub
End Class

#Region "Probeklassen"
Public Class MyDisposable : Implements IDisposable

    Private disposedValue As Boolean = False        ' To detect redundant calls
    Private Variable As Double = 42
    Private Form As frmGC

    Public Sub New(ByVal _Form As frmGC)
        Form = _Form
        Form.CurrentInstances += 1
    End Sub

    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: free other state (managed objects).
            End If

            ' TODO: free your own state (unmanaged objects).
            ' TODO: set large fields to null.
            Form.CurrentInstances -= 1
        End If
        Me.disposedValue = True
    End Sub

#Region " IDisposable Support "
    ' This code added by Visual Basic to correctly implement
    '  the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in 
        ' Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

End Class

Public Class MyInstance
    Private Variable As Double = 42

    Private Form As frmGC

    Public Sub New(ByVal _Form As frmGC)
        Form = _Form
        Form.CurrentInstances += 1
    End Sub

    Protected Overrides Sub Finalize()
        Form.CurrentInstances -= 1
    End Sub

End Class

#End Region

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.