Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. Possible memory leak

Possible memory leak

Scheduled Pinned Locked Moved Visual Basic
helpcsharptoolsperformance
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    dBrong
    wrote on last edited by
    #1

    I have written a document imaging system in VB.Net, using Pegasus tool kit. We have over 100 client's with no problems. However our latest client is experiencing problems. They have two users and both are having the same problem. The error message is to the affect: "attempt to read or write to protected memory" This is occuring after they open and close a scaning window numerous times over the course of 30 minutes. I made sure that I disposed of all the Pegasus tools (put msgbox()) in the window's dispose method. I don't create any 'fancy' objects, although I do open file streams. But I make sure they are closed, as I do for Sqlconnections and data readers. I put a garbage collector button in the parent window: GC.Collect() GC.WaitForPendingFinalizers() GC.Collect() GC.WaitForPendingFinalizers() MessageBox.Show("Done!" + vbCrLf + _ "Memory Allocated: " + GC.GetTotalMemory(False).ToString, "Garbage Collection") I can see the memory usage going up everytime I instantiate a new window. What's interesting is that from run to run the amount reported by GetTotalMemory is always different. Does anyone have any advice as how to approach this? Are there common VB objects that need to be manually disposed of? Thanks!

    S 1 Reply Last reply
    0
    • D dBrong

      I have written a document imaging system in VB.Net, using Pegasus tool kit. We have over 100 client's with no problems. However our latest client is experiencing problems. They have two users and both are having the same problem. The error message is to the affect: "attempt to read or write to protected memory" This is occuring after they open and close a scaning window numerous times over the course of 30 minutes. I made sure that I disposed of all the Pegasus tools (put msgbox()) in the window's dispose method. I don't create any 'fancy' objects, although I do open file streams. But I make sure they are closed, as I do for Sqlconnections and data readers. I put a garbage collector button in the parent window: GC.Collect() GC.WaitForPendingFinalizers() GC.Collect() GC.WaitForPendingFinalizers() MessageBox.Show("Done!" + vbCrLf + _ "Memory Allocated: " + GC.GetTotalMemory(False).ToString, "Garbage Collection") I can see the memory usage going up everytime I instantiate a new window. What's interesting is that from run to run the amount reported by GetTotalMemory is always different. Does anyone have any advice as how to approach this? Are there common VB objects that need to be manually disposed of? Thanks!

      S Offline
      S Offline
      Scott Dorman
      wrote on last edited by
      #2

      dBrong wrote:

      I put a garbage collector button in the parent window

      You really don't want to do this. Each time you call GC.Collect() you are freezing your applications main thread so the GC can run.

      dBrong wrote:

      Are there common VB objects that need to be manually disposed of?

      Any object that you are using that implements the IDisposable interface really should be cleaned up with a call to Dispose() or you should use it inside a using block. You specifically mention that you are opening streams and database connections, but how are you making sure that they are closed properly? If you aren't using a try/finally or a using block to ensure that the Close() or Dispose() method is being called even if an exception occurs then you aren't guaranteed that the objects will get cleaned up properly. Going beyond streams and database connections, since you are in an document imaging system, any Graphics objects or any image objects (Bitmap, Image, etc.) also should be cleaned up by calling Dispose(). These same rules apply for the Pegasus objects as well. If they aren't wrapped in a try/finally or a using block there is no guarantee that they are actually being cleaned up properly.

      Scott Dorman

      Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


      Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

      D 1 Reply Last reply
      0
      • S Scott Dorman

        dBrong wrote:

        I put a garbage collector button in the parent window

        You really don't want to do this. Each time you call GC.Collect() you are freezing your applications main thread so the GC can run.

        dBrong wrote:

        Are there common VB objects that need to be manually disposed of?

        Any object that you are using that implements the IDisposable interface really should be cleaned up with a call to Dispose() or you should use it inside a using block. You specifically mention that you are opening streams and database connections, but how are you making sure that they are closed properly? If you aren't using a try/finally or a using block to ensure that the Close() or Dispose() method is being called even if an exception occurs then you aren't guaranteed that the objects will get cleaned up properly. Going beyond streams and database connections, since you are in an document imaging system, any Graphics objects or any image objects (Bitmap, Image, etc.) also should be cleaned up by calling Dispose(). These same rules apply for the Pegasus objects as well. If they aren't wrapped in a try/finally or a using block there is no guarantee that they are actually being cleaned up properly.

        Scott Dorman

        Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


        Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

        D Offline
        D Offline
        dBrong
        wrote on last edited by
        #3

        Scott, Thanks for the response. I have a couple of questions: I figure that memory usage should always be the same. However each time I start the app, and call GC.GetTotalMemory I get a different value! Are there any system calls I can make to help me find out what's really happening with memory usage? Secondly, is there a list of .net objects that explicity need dispose() to be called manually? I'll wrap the close/dispose in try/catch. I was under the impression that if it failed I'd get a runtime error? Thanks.

        S G 2 Replies Last reply
        0
        • D dBrong

          Scott, Thanks for the response. I have a couple of questions: I figure that memory usage should always be the same. However each time I start the app, and call GC.GetTotalMemory I get a different value! Are there any system calls I can make to help me find out what's really happening with memory usage? Secondly, is there a list of .net objects that explicity need dispose() to be called manually? I'll wrap the close/dispose in try/catch. I was under the impression that if it failed I'd get a runtime error? Thanks.

          S Offline
          S Offline
          Scott Dorman
          wrote on last edited by
          #4

          dBrong wrote:

          Are there any system calls I can make to help me find out what's really happening with memory usage?

          There aren't any system calls you can make that I am aware of. There may be some unmanged Win32 API calls, but I'm not sure. The best option to see what is happening with the GC is to use some of the performance counters that are built in. Check this post[^] on Channel 9 for more information.

          dBrong wrote:

          Secondly, is there a list of .net objects that explicity need dispose() to be called manually?

          Unfortunately, there really isn't. The best option is to look at the following things:

          • Does the object provide a Close or Dispose method?
          • Does the object inherit from IDisposable?

          You can also look at the MSDN documentation or use Reflector to check as well. The best rule of thumb is that if the object "feels" like it should be disposed of after you're done using it, it probably implements IDisposable.

          dBrong wrote:

          I'll wrap the close/dispose in try/catch. I was under the impression that if it failed I'd get a runtime error?

          It all depends on how your objects (or the objects you are using) are implemented. If for some reason a disposable object were to throw an exception that was caught and eaten your calling code may not know about it and/or the call to Dispose may never occur. By putting the call to Dispose inside of a finally or using block you can guarantee that it will get called under all conditions.

          Scott Dorman

          Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


          Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

          1 Reply Last reply
          0
          • D dBrong

            Scott, Thanks for the response. I have a couple of questions: I figure that memory usage should always be the same. However each time I start the app, and call GC.GetTotalMemory I get a different value! Are there any system calls I can make to help me find out what's really happening with memory usage? Secondly, is there a list of .net objects that explicity need dispose() to be called manually? I'll wrap the close/dispose in try/catch. I was under the impression that if it failed I'd get a runtime error? Thanks.

            G Offline
            G Offline
            Guffa
            wrote on last edited by
            #5

            dBrong wrote:

            is there a list of .net objects that explicity need dispose() to be called manually?

            No, absolutely not. Such a list could never be complete, as the framework is growing with each new version, and there are thousands of thrird party libraries that contain objects that needs disposing. If in doubt, check if the object has a Dispose method. If it does, there is a reason for that. Not every class that implements IDisposable needs disposing, but unless you have determined that it's actually not needed, you should always call the Dispose method if there is one. Calling the Dispose method will not hurt even if it is not neccessary for that specific object. For example, you can close a SqlConnection object either by calling the Close method or the Dispose method, as the Dispose method makes sure that the Close method has been called. You can also call the Close method first, then the Dispose method, without harm. You can even call the Dispose method more than once on the same object without problems, you will never get an "object already disposed" error if you happen to call Dispose again.

            Despite everything, the person most likely to be fooling you next is yourself.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups