1. Trang chủ
  2. » Công Nghệ Thông Tin

Visual Basic 2005 Design and Development - Chapter 23 doc

36 178 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Memory Management
Trường học Standard University
Chuyên ngành Computer Science
Thể loại Chapter
Năm xuất bản 2007
Thành phố City Name
Định dạng
Số trang 36
Dung lượng 579,92 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Generally, you should assume that the garbage collector might run at any time and not worry about exactly when it runs.The garbage collector now performs garbage collection to free up me

Trang 1

Memory Management

Normally, developers take memory management for granted, and rightly so In most cases, the.NET memory-management system handles all the details about creating and destroying objects sothat you can concentrate on your application and not bookkeeping details

However, there are times when it’s useful to know a bit about how memory is managed in theapplication For certain types of applications, a few changes to the way you handle objects canmake a big difference in overall performance

This chapter explains how memory management works in Visual Basic It explains some niques you can use to minimize impact on the memory-management system, and it tells how tomake your memory use more efficient

tech-Before you can learn about specific techniques for managing memory, however, you must stand a little about how the memory system works In particular, you must know a bit about thegarbage collector

under-Garbage CollectionVisual Basic NET uses a garbage-collection memory-management scheme As a program creates

objects, the system takes unused memory from the managed heap When the program no longer has

any variables referring to an object, the object is freed and its memory is potentially available forreuse However, the garbage collector doesn’t yet know that the object has been freed

Over time, the program creates new objects and frees others Eventually, the managed heap runsout of free memory At that point, the garbage collector runs

Trang 2

Actually the garbage collector can execute whenever it thinks it will be profitable to do so That may be when the managed heap is really empty, or it may be when the garbage collector thinks enough objects have been freed that it would be a good idea to clean things up a bit Generally, you should assume that the garbage collector might run at any time and not worry about exactly when it runs.

The garbage collector now performs garbage collection to free up memory that was used, but is nolonger needed by the program

The garbage collector manages memory in multiple pieces called generations You can think of these as

multiple piles of trash with different distances from the door The generations closest to the door are ier to recycle than those farthest away

eas-Initially, the garbage collector sifts through the first pile of trash, called generation 0 (or Gen 0 or gen0)

rel-atively frequently When it can no longer find much usable space in generation 0, the garbage collector

recycles generation 1 When there isn’t much unused memory available in generations 0 or 1, it collects generation 2.

Again, this is a bit simplified The garbage collector can recycle any generation whenever it thinks that may be profitable In general, though, generation 0 collection happens relatively frequently, generation 1 collection happens less often, and generation 2 collection happens rarely.

When it recycles generation 0, the garbage collector finds the objects that are still in use and moves theminto a contiguous area in generation 1 so that they are collected less frequently in the future It thenreleases the unused memory in generation 0 for future use

Eventually, if an object lives long enough, the garbage collector promotes it from generation 1 to tion 2 Objects in generation 2 participate in garbage collections only rarely, so these objects will occupymemory for a fairly long time

genera-Note that the garbage collector need not always use three generations Currently, Visual Basic NET

uses three garbage generations, but future garbage collectors might use different strategies If you really need to know, use GC.MaxGenerationto find out how many generations are available This is

described in more detail later in this chapter.

Ideally, generation 0 contains short-lived objects that are allocated and released fairly quickly, generation

1 contains longer-lived objects that survive generation 0 garbage collection, and generation 2 containsvery long-lived objects that the program uses for a long time

The garbage collector is optimized to make generation 0 collection fast, generation 1 collection slower,and generation 2 collection slowest of all So, it’s important that generation 0 collection occurs mostoften, generation 1 collection occurs less often, and generation 2 collection occurs only rarely

For a good article that provides additional detail about how the garbage collector works, see msdn

.microsoft.com/msdnmag/issues/1100/gci.

586

Trang 3

F inalizationSome objects refer to other objects that are not controlled by managed NET code Because those objectsare not referred to by normal references, the garbage collector cannot clean them up automatically as itcan other objects.

For example, a Penobject uses graphics resources that are not managed by NET The garbage collectordoesn’t understand those resources, so it cannot manage them as it does managed objects

To free its unmanaged resources, the Penclass provides a Finalizemethod When the program tiates an object that has a Finalizemethod, the garbage collector adds the object to a finalization queue.

instan-Later, when the garbage collector discovers that the object is available for collection, it cannot destroy theobject because it has not yet been finalized Instead, the garbage collector removes the object from thefinalization queue and moves it to a list of objects that are ready for finalization The garbage collectorthen calls the Finalizemethods for the objects in the ready list, and removes them from that list.The next time the garbage collector runs, it will again find that these objects are inaccessible to the pro-gram This time, they are not in the finalization queue, so it can reclaim them It takes two garbage col-lections before these objects can be destroyed and their memory made available for reuse

Example program FinalizedClass(available for download at www.vb-helper.com/one_on_

one.htm) uses the following code to demonstrate finalization:

Public Class Form1Private Class BigPrivate BigArray(100000) As Integer

Protected Overrides Sub Finalize()Debug.WriteLine(“Finalize”)End Sub

Debug.WriteLine(“Allocate: Memory Allocated: “ & GC.GetTotalMemory(False))End Sub

‘ Release the object

Private Sub btnFree_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles btnFree.ClickDebug.WriteLine(“Freeing object”)

m_HasFinalize = NothingDebug.WriteLine(“Free: Memory Allocated: “ & GC.GetTotalMemory(False))End Sub

‘ Force garbage collection

Trang 4

Private Sub btnCollect_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles btnCollect.ClickGC.Collect()

Debug.WriteLine(“Collect: Memory Allocated: “ & GC.GetTotalMemory(False))End Sub

End Class

The Bigclass allocates a large chunk of memory and provides a Finalizemethod that displays a sage when the object is finalized

mes-When you click the Allocate button, the program makes a new Bigobject It then uses the GCclass’s

GetTotalMemorymethod to display the estimated amount of memory currently allocated

When you click the Free button, the program sets its reference to the Bigobject to Nothing At this pointthe object is a candidate for garbage collection, but garbage collection does not actually occur

When you click the Collectbutton, the program calls the GCclass’s Collectmethod to force garbagecollection in all generations The first time you click this button, the garbage collector removes the objectfrom the finalization list and calls its Finalizemethod The second time you click this button, thegarbage collector reclaims the object’s memory

The following text shows the output of one test:

Allocate: Memory Allocated: 1018164

Freeing object

Free: Memory Allocated: 1059124

Finalize

Collect: Memory Allocated: 936168

Collect: Memory Allocated: 503456

Collect: Memory Allocated: 503444

Collect: Memory Allocated: 503444

When I clicked the Allocate button, the program created the new object and reported roughly 1 millionallocated bytes of memory

When I clicked the Free button, the program freed its reference to the object and reported slightly morememory allocated

Next, I clicked the Collect button The garbage collector called the object’s Finalizemethod and theprogram reported that about 936,168 bytes were still allocated Some memory was reclaimed, but theobject’s memory is still not completely available

When I clicked the Collect button again, the garbage collector finally freed the object and the programreported much less memory allocated In fact, the program reports approximately 400,000 fewer bytesallocated and the Bigobject occupies roughly 400,000 bytes (100,000 times 4 bytes per Integer in thearray) It is only during this second garbage collection that the object is truly free

588

Trang 5

Disposing Resources

An object that has a Finalizemethod is only completely freed after two garbage-collection passes Thefirst pass calls the object’s Finalizemethod to release unmanaged resources The second pass actuallyreleases the object’s memory

Not only does this mean that the garbage collector must run twice to clean up these objects, but it alsomeans the program has little control over when the objects’ Finalizemethods are eventually called.Your program generally doesn’t have much control over when the garbage collector runs, so there’s noobvious way for you to know when the Finalizemethod executes If you need Finalizeto runquickly, that can be a problem For example, suppose a class writes data into a file and then closes thefile in its Finalizemethod Because you don’t know when that will occur, you cannot rely on the filebeing closed later

Because you don’t know when a Finalizemethod will be called, this garbage-collection strategy is

called non-deterministic finalization.

You can make garbage collection more efficient and more predictable if you dispose of the object’sresources without waiting for garbage collection You know immediately that the object’s resources arefree and the next garbage collection will reclaim the object completely without requiring a second pass.You can free a standard NET Framework object’s unmanaged resources by calling its Disposemethod.The Disposemethod frees the object’s unmanaged resources and then calls the GCclass’s

SuppressFinalizeroutine to tell the garbage collector that it no longer needs to call the object’s

The Usingkeyword makes disposing of these kinds of objects automatic If you declare the object in a

Usingstatement, Visual Basic automatically calls the object’s Disposemethod when it exits the Using

block

The following code shows how example program UsingPen(available for download at www.vb-helper.com/one_on_one.htm) draws an ellipse It defines a Penobject named red_penin a Usingstatement.Then it reaches the End Usingstatement, and the program automatically calls the Pen’s Disposemethod

Private Sub Form1_Paint(ByVal sender As Object, _ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.PaintUsing red_pen As New Pen(Color.Red, 5)

Dim rect As New Rectangle(10, 10, _Me.ClientSize.Width - 20, Me.ClientSize.Height - 20)e.Graphics.DrawEllipse(red_pen, rect)

End UsingEnd Sub

Trang 6

AUsingblock always calls the object’s Disposemethod whether the program exits the block by using

an Exitor Returnstatement, by throwing an exception, or by some other method

Disposing Custom Classes

If you build a class that uses unmanaged resources, you should make the class implement the

IDisposableinterface so that it can properly handle finalization and the Disposemethod

If you start a new class, type Implements IDisposable, and press Enter, Visual Basic fills in some of the

code you need to build a disposable class for you Unfortunately, in the version I’m running, at least, thecode is incomplete (it doesn’t include a Finalizemethod) and misleading (some of the comments arewrong) The following code shows a more complete and correct version:

Public Class Big

Implements IDisposable

‘ Indicates whether we have already been disposed

Private m_WasDisposed As Boolean = False

‘ Dispose of resources

Protected Overridable Sub Dispose(ByVal disposing As Boolean)

If Not m_WasDisposed Then

If disposing Then

‘ Dispose was called explicitly

‘ Free managed resources

‘ TODO: Free the managed resources

End If

‘ Free unmanaged resources

‘ TODO: Free the unmanaged resources

End If

m_WasDisposed = TrueEnd Sub

‘ Dispose of resources explicitly

‘ Do not change this code Make changes

‘ to the other version of Dispose

Public Sub Dispose() Implements IDisposable.DisposeDispose(True)

GC.SuppressFinalize(Me)End Sub

‘ Finalize the object

Protected Overrides Sub Finalize()

‘ Call Dispose passing False to indicate that

‘ we are not running from a program call to Dispose()

Dispose(False)End Sub

End Class

590

Trang 7

The m_WasDisposedvariable remembers whether the object’s resources have already been disposed.The first version of the Disposesubroutine uses this value to only dispose of its resources once If themain program accidentally calls the object’s Disposemethod twice, the code does nothing during thesecond call.

The first version of Disposetakes a parameter named disposingthat tells it whether the routine isbeing called explicitly or implicitly by the Finalizemethod If disposing is True, then Dispose

releases all of the object’s managed and unmanaged resources If disposing is False, then Dispose

releases only its managed resources

At first, this may seem strange Why shouldn’t the code dispose of managed resources when it is beingcalled from Finalize? The reason is that it is not safe to refer to objects that are being finalized There’s

no way to determine the order in which objects will be finalized, and the program will throw an tion if it tries to refer to another object that has already been finalized

excep-How could this happen? Suppose you have a group of several objects that refer to each other If no other variable in your program refers to any of those objects, the garbage collector will not mark them as in use and will collect them all It’s anybody’s guess which objects are collected first, so they must not try

to refer to each other during finalization.

In many cases, non-managed resources use handles to operating system objects that are not representedby.NET Framework objects Often, you can use the SafeHandleclass and its descendants to managethese resources safely without implementing IDisposableyourself

For example, the SafeFileHandleclass providers a wrapper for file handles It provides IsClosedand

IsInvalidmethods to indicate whether a handle is open and valid Its Closeand Disposemethodsclose the object’s file handle

Before you start writing your own class to deal with an unmanaged handle, check the SafeHandleclassand its descendants to see if one of them already meets your needs

Pre-allocating ObjectsNormally, your programs should ignore garbage collection and let the garbage collector do its job with-out interference Occasionally, you may be able to improve performance if you know something specialabout how the application works

For example, suppose you know that your program is about to create several thousand objects, but itwill not need them all at the same time Suppose the program is about to perform 10,000 calculationsduring each of which it will allocate around 100 objects If you let the garbage collector handle allocationand deallocation as usual, the program will create and destroy around 1 million objects (10,000 calcula-tions times 100 objects) Depending on the size of the objects, that may lead to several rounds of garbagecollection

Instead of following this “use it and lose it” strategy, suppose the program pre-allocates 100 objects andreuses them as necessary In that case, the program only creates and destroys 100 objects, so it is unlikelythat it will need to perform garbage collection even once

Trang 8

Example program Preallocate(available for download at www.vb-helper.com/one_on_one.htm)compares these two strategies When you click the Run button, the program performs a large number oftrials where it builds a linked list of 100 Cellobjects.

The following code shows the Cellclass The MyFormvariable refers to the program’s main form

Valuesis an array of integers that just uses up some memory NextCellis a reference to the next cell inthe current list

Public Class Cell

Public MyForm As Form1

Public Values(100) As IntegerPublic NextCell As Cell

Public Sub New(ByVal new_MyForm As Form1)MyForm = new_MyForm

End Sub

Protected Overrides Sub Finalize()

If MyForm.GCRunning Then Exit SubDebug.WriteLine(“Garbage collecting “ & MyForm.NumGCs & “ ”)MyForm.GCRunning = True

MyForm.NumGCs += 1End Sub

End Class

The Cellclass’s Finalizemethod checks the form’s GCRunningvariable and exits if the value is True.Otherwise, the method prints a message indicating that garbage collection is occurring, sets the form’s

GCRunningvariable to True, and increments the garbage-collection count

The following code shows how program Preallocateresponds when you click the Run button:

Public GCRunning As Boolean = False

Public NumGCs As Integer = 0

Private Sub btnRun_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles btnRun.Click

Dim start_time As Date = Now

NumGCs = 0Dim num_trials As Long = Long.Parse(txtNumTrials.Text)For i As Long = 1 To num_trials

‘ Allocate a bunch of objects

Dim top As New Cell(Me)top.NextCell = Nothing

For j As Integer = 1 To 99Dim new_cell As New Cell(Me)new_cell.NextCell = toptop = new_cell

Next j

‘ Free the objects

592

Trang 9

top = NothingGCRunning = FalseNext i

‘ Force a final GC

GC.Collect()Debug.WriteLine(“Done”)

Dim stop_time As Date = NowDim elapsed_time As TimeSpan = stop_time.Subtract(start_time)Debug.WriteLine(“Elapsed time: “ & elapsed_time.TotalSeconds.ToString(“0.00”))End Sub

After recording its start time, the program loops through a number of trials For each trial, it builds alinked list of 100 Cellobjects It then sets the topmost object to Nothing, so the program no longer has areference to the objects and they are candidates for garbage collection

If garbage collection occurs, any cells that are available for garbage collection execute their Finalize

methods The first of those objects displays a message and sets the form’s GCRunningvariable to True.After collection is complete, the program resets GCRunningto Falseso Cellsthat are finalized laterdisplay a new message

The routine finishes by displaying the elapsed time

The following code runs when you click the program’s Preallocate & Run button:

Private Sub btnPreallocateRun_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles btnPreallocateRun.ClickDim start_time As Date = Now

NumGCs = 0

‘ Preallocate some Cell objects

Dim available(100) As Cellavailable(available.Length - 1) = New Cell(Me)available(available.Length - 1).NextCell = NothingFor i As Integer = available.Length - 2 To 0 Step -1available(i) = New Cell(Me)

available(i).NextCell = available(i + 1)Next i

Dim top_available As Cell = available(0)

‘ Perform the trials

Dim num_trials As Long = Long.Parse(txtNumTrials.Text)For i As Long = 1 To num_trials

‘ Allocate a bunch of objects

Dim top As New Cell(Me)top.NextCell = Nothing

For j As Integer = 1 To 99Dim new_cell As Cell = top_availabletop_available = top_available.NextCell

new_cell.NextCell = top

Trang 10

top = new_cellNext j

‘ Free the objects

Dim last_cell As Cell = top_available

Do While last_cell.NextCell IsNot Nothinglast_cell = last_cell.NextCell

Looplast_cell.NextCell = toptop = Nothing

GCRunning = FalseNext i

‘ Deallocate the objects

top_available = NothingErase available

‘ Force a final GC

GC.Collect()

Dim stop_time As Date = NowDim elapsed_time As TimeSpan = stop_time.Subtract(start_time)Debug.WriteLine(“Elapsed time: “ & elapsed_time.TotalSeconds.ToString(“0.00”))End Sub

This code starts by pre-allocating an array of 101 Cellobjects It initializes the objects so that they form

a linked list and sets top_availableto refer to the first object in the array

The program then performs its trials much as before This time, however, it doesn’t create new Cell

objects from scratch Instead, when it needs a new Cellobject, it takes one from the top of the availablelist When it finishes a trial, the program places the Cells it has used back in the available array for laterreuse

After it finishes its trials, the program sets top_availableto Nothingand erases the available array sothe program has no references to the Cellobjects It forces a final garbage collection and displays theelapsed time

In one test, letting the garbage collector run without interference required eight garbage collections andtook 5.28 seconds Pre-allocating the Cellobjects required a single garbage collection at the end andtook 1.17 seconds

This example demonstrates a very special case Usually, the garbage collector does just fine by itself, but

if you know that the program must repeatedly allocate and deallocate many objects while keeping only

a few alive at one time, then you may be able to improve performance by pre-allocating the objects.There is a danger to using this method, however If garbage collection runs while the pre-allocatedobjects are in use, they will be promoted to generation 1 That will mean they will not be candidates forfuture garbage collection until the garbage collector performs generation 1 garbage collection, whichcould be quite awhile later Of course, it’s entirely possible that a lot of the temporary objects would be

in use if you leave the garbage collector alone, so it’s not certain that pre-allocating objects is worse

594

Trang 11

You can call GC.Collect(1)to force a generation 1 garbage collection when the long series of lations is finished.

calcu-Usually, you should leave the garbage collector alone and only tamper with its behavior if you know theprogram has a special structure (as in this example) and you know you are having performance problems

Weak References

If a program uses a lot of very large objects, it can quickly use up a lot of memory If the program usestoo much memory, it may spend a lot of time paging to the system’s page file It may also spend a lot oftime performing garbage collection and it may have a lot of objects stuck in generation 1 or 2

One way to avoid these problems is to not save large objects Instead of storing large objects for later use,some programs can release the objects and re-create them later when they are needed Unfortunately,this solution makes the program spend extra time rebuilding the objects when they are needed

The WeakReferenceclass provides a compromise It lets a program keep a reference to an object forlater use If the program runs low on memory, however, the garbage collector is allowed to reclaim theobject If that happens, the program must re-create the object when it needs it again The program gets abit of the advantages of both scenarios: the large object doesn’t tie up memory permanently, but some-times it’s still available, so the program doesn’t need to re-create it

To use a weak reference, create a WeakReferenceobject and set its Targetproperty to the object youwant to save If the program has other “strong” references to the object, then the object is not availablefor garbage collection If the WeakReferenceobject’s Targetproperty is the only reference to the object,the garbage collector can reclaim the object if necessary

Example program WeakReferences(available for download at www.vb-helper.com/one_on_

one.htm) shown in Figure 23-1 stores weak references to large objects Each time you click the Allocatebutton, the program creates a new large object and saves a WeakReferencepointing to it When mem-ory becomes too full, the garbage collector runs and reclaims some of the weakly referenced objects

Figure 23-1: Program WeakReferencesdemonstrates weakreferences to large objects

In Figure 23-1, I clicked the Allocate button eight times The first four times, the program created newobjects When I clicked the button the fifth time, the program created another large object While the

Trang 12

code still had a temporary strong reference to the object, the program ran the garbage collector The lector reclaimed the first four objects and promoted the new object to generation 1 At that point, the but-ton’s Clickevent handler exited, so the only reference the program had to the new object was its weakreference.

col-Next, I clicked the Allocate button three more times and the program created more objects with weakreferences If I were to click the button again, the program would repeat the previous round of garbagecollection: make a new object, reclaim the previous objects, and promote the new object to generation 1.The following code shows the Bigclass that program WeakReferencesuses to allocate approximately

256 KB of memory Its Valuesvariable is an array that occupies 256 KB The constructor and Finalize

methods display messages in the Outputwindow so that you can see when objects are created anddestroyed

‘ A Big object occupies about 256 KB

Public Class Big

Private Const KB256 As Integer = 1024 * 256Private Values(KB256) As Byte

Public Name As Integer

Public Sub New(ByVal new_Name As Integer)Name = new_Name

Debug.WriteLine(“Created “ & Name)End Sub

Protected Overrides Sub Finalize()Debug.WriteLine(“Destroyed “ & Name)End Sub

End Class

The following code shows how program WeakReferencesuses the Bigclass The m_WeakReferences

list holds the WeakReferenceobjects that point to the Bigobjects

Private m_WeakReferences As New List(Of WeakReference)

‘ Allocate a new object

Private Sub btnAllocate_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles btnAllocate.Click

‘ Make the new Big object

Dim new_big As New Big(m_WeakReferences.Count + 1)

‘ Associate it with a WeakReference object

Dim weak_reference As New WeakReference(new_big)m_WeakReferences.Add(weak_reference)

‘ Display information about the active objects

lstObjects.Items.Clear()For Each wr As WeakReference In m_WeakReferences

If wr.IsAlive ThenDim the_big As Big = _DirectCast(wr.Target, Big)lstObjects.Items.Add(“Generation “ & GC.GetGeneration(the_big) & _

“, Object “ & the_big.Name)

596

Trang 13

ElselstObjects.Items.Add(“<Dead object>”)End If

Next wr

Debug.WriteLine(“Memory Allocated: “ & GC.GetTotalMemory(False))End Sub

When you click the Allocate button, the program creates a new Bigobject While the variable new_bigis

in scope, the program has a strong reference to this object, so it is not a candidate for garbage collection.Next the program creates a WeakReferenceobject The object’s constructor sets its Targetproperty tothe new Bigobject

The program clears its list box and the loops through the WeakReferenceobjects in the m_WeakReferenceslist AWeakReferenceobject’s IsAliveproperty returns Trueif the WeakReference’s

Targetobject is still available, and returns Falseif the Targetobject has been reclaimed by thegarbage collector If the object is still alive, the program uses DirectCastto convert the Targetvalueinto a Bigobject and displays the object’s Nameproperty If the object is dead, then the program simplysays so

If a WeakReferenceobject’s IsAliveproperty is False, its Targetproperty is Nothing.

Unfortunately, there is no way to prioritize weak references For example, it might be nice to indicatethat the garbage collector should reclaim some objects before others, that it should only reclaim an object

if it is performing a generation 1 or 2 collection, or that it should reclaim an object if a certain percentage

of the available memory is in use You can make strong or weak references to an object, but that’s theonly control you have over this

Improving Garbage CollectionNormally, the garbage collector does fine on its own But there are a few considerations that you cankeep in mind while developing to make the garbage collector a bit more effective

Most importantly, don’t let your program hold on to large numbers of objects for a long time If the gram is holding a lot of objects when a garbage collection occurs, those objects will be promoted to gen-eration 1 That not only takes longer than freeing the objects if they were not in use, but it also means theprogram will need to spend extra time later freeing those objects again during a generation 1 garbagecollection

pro-If the program will use an object frequently over a long time, keeping a reference to the object makessense If the object is used only infrequently, use it and lose it Pens and brushes are good examples.Suppose an application uses a class to represent items (ellipses, rectangles, text, and so forth) that itdraws during its Paintevent You could store a pen and brush to draw each item in its class A betterapproach is to store information about the pen and brush that an object needs Then, each object can re-create its pen and brush when it needs to draw The garbage collector is designed to reclaim many smallobjects such as pens and brushes frequently, so it’s better to do so than to make these objects stickaround for a long time

Trang 14

If an object has a Disposemethod, use it when you are done with the object That allows the garbagecollector to reclaim the object in a single pass, instead of merely running the object’s Finalizemethod

in one pass and then reclaiming the object in the next The Usingstatement makes calling the Dispose

method automatic, so use it when you can

Because finalizers take awhile to execute and prevent the garbage collector from reclaiming an object in

a single pass, avoid building Finalizemethods If an object uses a resource that must be freed whenthe object is destroyed, by all means, build a finalizer But if there’s another way to structure the pro-gram to avoid this, use it If you do write a Finalizeroutine, also write a Disposemethod and call itwhen you are finished with the object

Release temporary objects before starting a long calculation, particularly if the calculation will use lots ofmemory If the calculation causes a garbage collection, then the fewer objects you have loaded the better

If the code has just finished a very involved calculation, you may have reason to believe that manyunused objects are available for reclamation In particular, if you think a lot of objects are in generation 1and 2, you may get some benefit from flushing them out by calling GC.Collect A parameter to

GC.Collecttells the garbage collector what generation to collect If you omit the parameter, it collectsgarbage in all generations

When you call GC.Collect, the garbage collector only runs the Finalizemethods for any objects thatare in the finalization queue To ensure that the finalizers have a chance to run, you can call

GC.WaitForPendingFinalizers Then you can reclaim those objects by calling GC.Collectagain, asshown in the following code:

GC.Collect() ‘ Reclaim unused objects and run finalizers.GC.WaitForPendingFinalizers() ‘ Wait for finalizers to finish

GC.Collect() ‘ Reclaim objects that ran finalizers

You can help the garbage collector by minimizing the program’s use of objects The fewer objects theprogram uses, the less often it will need to perform garbage collection

Finally, reduce the program’s use of references When the garbage collector runs, it must follow everyobject reference to mark the target object as in use If your data structures have a lot of references, thegarbage collector must do a lot of work

Example program ManyReferences(available for download at www.vb-helper.com/one_on_one.htm)shown in Figure 23-2 allocates an array of Cellobjects Enter the number of objects you want to createand click the MakeObjectsbutton Click the Collectbutton to force garbage collection The programdisplays the elapsed number of seconds in the label below the button

Figure 23-2: Program ManyReferencescan make the garbagecollector follow a huge number of references

598

Trang 15

Each Cellobject has a Neighborsproperty that contains a list of references to other Cellobjects If youleave the Many References box unchecked when you create objects, the program gives each Cella sin-gle neighbor If you check the Many References box, the program adds every Cellto every other Cell’sneighbor list.

In Figure 23-2 the program created 10,000 objects, each having 9,999 neighbors for a total of slightly lessthan 100 million neighbor references Performing garbage collection while these objects were allocatedtook 1.11 seconds Note that there were no unused objects available for the garbage collector to reclaim.All of these references were contained in active objects, so the garbage collector was forced to followthem all Just having all of these references around makes garbage collection slower

When I ran the test without the Many References button checked, the program created only 10,000neighbor references and took around 0.01 seconds to perform garbage collection

The program also took almost no time to perform garbage collection as soon as the highly linked objects were destroyed, even though the objects and their references were still around waiting for garbage collec- tion The garbage collector only needs to follow references that are reachable from the program’s vari- ables, so references contained in unused objects don’t slow performance.

Summar yUsually, you should ignore the garbage collector and focus on the application’s code The garbage collec-tor is designed to reclaim unused memory fairly efficiently, and meddling with the way it works oftendegrades its performance

To make garbage collection as efficient as possible, always call an object’s Disposemethod when youare finished with it When you build your own classes, avoid using a Finalizemethod if you can Ifyou must use Finalize, also provide a Disposemethod and use it

In some applications, you can improve performance by pre-allocating objects before using them, or byforcing garbage collection after a long calculation has promoted many items to generation 1 or 2 Thesemeasures can interfere with the garbage collector’s normal behavior, however, so only consider them ifyou have special information about the application that indicates that they will help and you know thatthere is a performance problem In most cases, the garbage collector does just fine without extra help.Finally, use the WeakReferenceclass to keep references to large objects that you may need later but thatyou can re-create if necessary These allow you to reuse objects sometimes without unduly restricting thegarbage collector

Trang 17

<< (double less-than sign), unfolding dialog, 106

<example>comment tag, 357

<summary>comment tag, 357

UI design, 122About dialog box, 496–497, 500acceptance testing, 59Access (Microsoft), 139accidents, happy, 16activity diagrams, UML, 86–87adapter class relation patterns, 171AddConstructorDatasubroutine, 563–564add-ins

code, adding, 227–230creating, 222–226DelegationAddInproject, 231–236described, 222

improving, 230–231advise, don’t act philosophy, 99–100

Agile and Iterative Development (Larman), 50

agile programmingCrystal Clear methodology, 51–52DBC, 62–67

described, 49–51Microsoft tools, 67–68strengths and weaknesses, 61–62tools, using all, 405–406traditional lifecycles versus, 60–61XP

acceptance testing, 59coding standard, 54collective code ownership, 54continuous integration, 54

Trang 18

agile programming (continued)

Aguanno, Kevin (Managing Agile Projects), 50

algorithms, classes representing, 199–200

Anti Patterns, Refactoring Software, Architectures, and

Projects in Crisis (Brown), 201

attributesAssignJobsubroutine, 329–330code editor

AttributeUsage, 340ComClassAttribute, 340Conditional, 340–341DebuggerHidden, 342DebuggerStepThrough, 342EditorBrowsable, 342Flags, 342

HideModuleName, 343Obsolete, 343ProvideProperty, 343described, 330–332form designerDefaultEvent, 339Docking, 339ToolboxBitmap, 340ToolboxItem, 340Properties windowAmbientValue, 332Browsable, 332Category, 332–333DefaultProperty, 333DefaultValue, 333Description, 333–334Designer, 334DisplayName, 334Editor, 335Localizable, 335NotifyParentPropertyAttribute, 335–336ParenthesizePropertyName, 336

PasswordPropertyText, 336PropertyTab, 336–338ReadOnly, 335RefreshPropertiesAttribute, 338–339TypeConverter, 339

recommendations, 355–356serialization

OnDeserializing, OnDeserialized,OnSerializing, and OnSerialized, 344OptionalField, 344–345

Serializable, 344XmlArray, 345XmlArrayItem, 345XmlAttribute, 345–346XmlElement, 346XmlEnum, 346

602

Ngày đăng: 14/08/2014, 11:20

TỪ KHÓA LIÊN QUAN