How to release the occupied memory

2020-01-29 19:11发布

I have a main window in my project, and numerous other child widows inside the main.
I have noticed that. When I open the main window occupies 1500K of memory, when open one child window then adds in occupied memory 6000K.
When I open the second window doing the same. When I close the two child windows the occupied memory is not released.
So What I want is to release the occupied memory when ever I close child windows.
How I can do that?
Please advice me with some code example in vb.net if it is possible.
This problem often sawing in the computers on the Local NET not in my computer (developer computer which has the SQL server on it).

7条回答
够拽才男人
2楼-- · 2020-01-29 19:26

Using as suggested by Pranay will work as it will by default call Dispose method. else explicitly you have to call this.dispose() after calling this.close() on your child forms. But be sure you are not going to use child form elements or value after close. Since dispose will finally clear everything.

MSDN example for disposing unmanaged resource

Imports System
Imports System.ComponentModel

' The following example demonstrates how to create
' a resource class that implements the IDisposable interface
' and the IDisposable.Dispose method.
Public Class DisposeExample

   ' A class that implements IDisposable.
   ' By implementing IDisposable, you are announcing that 
   ' instances of this type allocate scarce resources.
   Public Class MyResource
      Implements IDisposable
      ' Pointer to an external unmanaged resource.
      Private handle As IntPtr
      ' Other managed resource this class uses.
      Private component As component
      ' Track whether Dispose has been called.
      Private disposed As Boolean = False

      ' The class constructor.
      Public Sub New(ByVal handle As IntPtr)
         Me.handle = handle
      End Sub

      ' Implement IDisposable.
      ' Do not make this method virtual.
      ' A derived class should not be able to override this method.
      Public Overloads Sub Dispose() Implements IDisposable.Dispose
         Dispose(True)
         ' This object will be cleaned up by the Dispose method.
         ' Therefore, you should call GC.SupressFinalize to
         ' take this object off the finalization queue 
         ' and prevent finalization code for this object
         ' from executing a second time.
         GC.SuppressFinalize(Me)
      End Sub

      ' Dispose(bool disposing) executes in two distinct scenarios.
      ' If disposing equals true, the method has been called directly
      ' or indirectly by a user's code. Managed and unmanaged resources
      ' can be disposed.
      ' If disposing equals false, the method has been called by the 
      ' runtime from inside the finalizer and you should not reference 
      ' other objects. Only unmanaged resources can be disposed.
      Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
         ' Check to see if Dispose has already been called.
         If Not Me.disposed Then
            ' If disposing equals true, dispose all managed 
            ' and unmanaged resources.
            If disposing Then
               ' Dispose managed resources.
               component.Dispose()
            End If

            ' Call the appropriate methods to clean up 
            ' unmanaged resources here.
            ' If disposing is false, 
            ' only the following code is executed.
            CloseHandle(handle)
            handle = IntPtr.Zero

            ' Note disposing has been done.
            disposed = True

         End If
      End Sub

      ' Use interop to call the method necessary  
      ' to clean up the unmanaged resource.
      <System.Runtime.InteropServices.DllImport("Kernel32")> _
      Private Shared Function CloseHandle(ByVal handle As IntPtr) As [Boolean]
      End Function

      ' This finalizer will run only if the Dispose method 
      ' does not get called.
      ' It gives your base class the opportunity to finalize.
      ' Do not provide finalize methods in types derived from this class.
      Protected Overrides Sub Finalize()
         ' Do not re-create Dispose clean-up code here.
         ' Calling Dispose(false) is optimal in terms of
         ' readability and maintainability.
         Dispose(False)
         MyBase.Finalize()
      End Sub
   End Class

   Public Shared Sub Main()
      ' Insert code here to create
      ' and use the MyResource object.
   End Sub

End Class

(Update)[Check]

If your child form has the signature. These are by default added to a form.

'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
    MyBase.Dispose(disposing)
End Sub
查看更多
Summer. ? 凉城
3楼-- · 2020-01-29 19:35

Some of the other answers to this question contain a disappointing amount of misinformation, while others vastly over-complicate the issue. There are a lot of misconceptions surrounding garbage collection in .NET, and the theories being bandied about here are certainly not helping the problem.

First of all, profiling memory usage with Windows Task Manager is a huge mistake. You will get seriously invalid information, and attempting to modify your application according to this information is only going to make things worse, rather than better. If you suspect that you have performance problems (and it's very doubtful that the majority of applications actually will experience any), you need to invest in a proper memory profiler and use that instead.

Second, the whole point of garbage collection is that you don't have to worry about this kind of thing. And not only do you not have to worry about it, but you shouldn't worry about it, either. You should not be doing or attempting any type of manual memory management when writing applications targeting the .NET Framework. Resist the temptation to tinker with the internal workings of the garbage collector, and plant your fingers firmly in your ears when anyone tells you to call GC.Collect manually to force a garbage collection to occur. I suppose I shouldn't say never, but there is hardly ever a reason to do this. I'm far more likely to be suspect of code that manually invokes garbage collection than anything else.

Why shouldn't you manually invoke garbage collection? Well, beyond the obvious argument that it defeats the whole point of using a managed language in the first place, it's because garbage collection is an arduously slow and expensive process. You want it to run as rarely as possible in order to maintain peak performance. Fortunately, the programmers who implemented the garbage collection algorithms are much smarter and more experienced than either you or I: they designed it to run only when necessary, and no more often than that. You won't see an advantage of running it more often, but you will see a disadvantage. This is supposed to be completely opaque to you as the programmer.

The only exception is when you're working with unmanaged objects, which are not collected or managed by the garbage collector. You'll be able to recognize these objects because they all implement the IDisposable interface, which provides a Dispose method to release unmanaged resources. On objects that expose this method, you should call it as soon as you finish using the object. Or better yet, wrap the declaration and use of the object in a using statement, which will automatically handle disposing the object, no matter what happens (even if an exception is thrown in the code where you use the object, for example).

Of course, you will notice that several of the standard objects in the Windows Forms library implement the IDisposable method. The ubiquitous Form class, for example, provides a Dispose method. However, that does not necessarily mean that you are responsible for disposing of these objects manually. In general, you only need to explicitly call the Dispose method for objects that you explicitly create—easy to remember, right? The objects created automatically by the Framework are also automatically destroyed by the Framework. For example, the controls you place on a Form object at design-time are automatically disposed when their container form is disposed. And Form objects themselves are automatically disposed when they are closed. This is particularly relevant to the issue brought up in your question. The documentation for the Form.Close method tells us this:

When a form is closed, all resources created within the object are closed and the form is disposed.

[ . . . ]

The two conditions when a form is not disposed on Close is when (1) it is part of a multiple-document interface (MDI) application, and the form is not visible; and (2) you have displayed the form using ShowDialog. In these cases, you will need to call Dispose manually to mark all of the form's controls for garbage collection.

Notice that, in general, you won't find yourself ever having to call Form.Dispose manually from your code. It's impossible for a user to close a MDI child form when its MDI parent is not visible, and if you happen to close the form yourself in code when its parent is invisible, you can simply insert a call to Form.Dispose. When you show a form as a modal dialog using the ShowDialog method, you can conveniently wrap its creation and use in a using statement.

Now, recall that simply calling the Dispose method on an object only releases unmanaged resources and marks the object as available for garbage collection. It does not immediately release the memory claimed by that object. This is important, because it's exactly what your attempts at memory profiling were focused on. You know that the objects are being disposed, because you mention that the variables become unavailable to you (you say that you're "losing their values"). That's because you cannot access disposed objects. That doesn't necessarily imply, however, that the memory they claimed has been fully released. Doing so is the job of the garbage collector, which we've already established you're not supposed to monkey with. It will wait to release the memory until the application is either idle, or it desperately needs to reuse that memory. Otherwise, it will postpone collection, and that's still OK.

查看更多
我只想做你的唯一
4楼-- · 2020-01-29 19:39

I'm no expert in VB.net but as far as I know it has a garbage collector. That normally means that closing the child windows does not free memory but if you remove all references to the child windows the garbage collector might free it in the next run.

Additionally, you normally can "ask" the garbage collector to run but it normally does "decide" by itself when to run.

查看更多
我命由我不由天
5楼-- · 2020-01-29 19:40

make use of using block , which atomatically release memory

Using { resourcelist | resourceexpression }
    [ statements ]
End Using
查看更多
闹够了就滚
6楼-- · 2020-01-29 19:48

That's someting you shouldn't care about.

The .NET Framework Garbage Collector will do this work for you.

The .NET Framework's garbage collector manages the allocation and release of memory for your application. Each time you create a new object, the common language runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects.

Edit:

You have to make sure you're not using the resouces you wat to be free anymore. Garbage Collector's functionalities are located in the class GC under the namespace System.

In order to invoke it, you can do GC.Collect(), although I suggest you reading more about this topic and see some examples like this one

查看更多
一夜七次
7楼-- · 2020-01-29 19:48

The garbage collector will do the work for you, so you really should not mind about it. You should have a more deep look inside if and only if you are using unmanaged resources ( com interop/PInvoke ).

查看更多
登录 后发表回答