Problem with "handles" - possible garbage collection issue?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Simon Verona

    Problem with "handles" - possible garbage collection issue?

    I have a problem in my application which I believe is due to open handles.. .

    The symptom that users report is that after they have been using the application for a while, it will randomly just crash with an exception report (I've not got the details of the error, but I'm working on that now!).

    I'm trying to reproduce the circumstances by simulating a typical batch of user tasks on my pc and monitoring whats happening. I'm guessing it's some problem with threads/handles or something so I've opened up the task manager and added all the available columns.

    What I've noticed is that whilst the application is running, the memory usage keeps increasing, but more worrying, the no of open handles just keeps going up and up (it's nearly 4000 handles after running through about 30 tasks).

    What the application is doing is as follows:

    I have a main form showing, which displays a list from a database.

    Then what I'm doing is clicking down the list one by one..

    What this does is to open a form on another thread to stop it blocking the main window. It does this as follows

    =====
    Private sub Click(rowno as int32)
    dim vehicle as new dmsvehicle.vehi cle
    vehicle.showveh icle(Data(rowno ))
    end sub
    =====

    The Vehicle.showveh icle subroutine is as follows:

    ====
    public sub ShowVehicle(Sto ckNo)
    Dim frm As New ViewVehicleStat us(StockNo)

    Dim t As New Threading.Threa d(AddressOf frm.dmsShowDial og)

    'frm.StockNo = StockNo

    t.Start()

    end Sub

    ====

    The "dmsShowDia log" subroutine in the form is simply doing a me.showdialog.



    This all seems to work fine, and when I close the form I see a message such as "The thread '<No Name>' (0x6ec) has exited with code 0 (0x0)." appear in the output window of the development environment.

    However, the no of handles just keeps increasing - I presumed that the garbage collector should tidy up every now and then, but thats not what I'm seeing.

    I've not actually duplicated the users issue yet (but I have a high spec machine with masses of memory), but I suspect that this will be the cause of their problem?

    Any suggestions as to what I've done wrong?

    Thanks in advance

    Simon






  • Armin Zingler

    #2
    Re: Problem with &quot;handles&q uot; - possible garbage collection issue?

    "Simon Verona" <news@aphrodite uk.com> schrieb[color=blue]
    > I have a problem in my application which I believe is due to open
    > handles.. .
    >
    > The symptom that users report is that after they have been using the
    > application for a while, it will randomly just crash with an
    > exception report (I've not got the details of the error, but I'm
    > working on that now!).
    >
    > I'm trying to reproduce the circumstances by simulating a typical
    > batch of user tasks on my pc and monitoring whats happening. I'm
    > guessing it's some problem with threads/handles or something so I've
    > opened up the task manager and added all the available columns.
    >
    > What I've noticed is that whilst the application is running, the
    > memory usage keeps increasing, but more worrying, the no of open
    > handles just keeps going up and up (it's nearly 4000 handles after
    > running through about 30 tasks).
    >
    > What the application is doing is as follows:
    >
    > I have a main form showing, which displays a list from a database.
    >
    > Then what I'm doing is clicking down the list one by one..
    >
    > What this does is to open a form on another thread to stop it
    > blocking the main window. It does this as follows
    >
    > =====
    > Private sub Click(rowno as int32)
    > dim vehicle as new dmsvehicle.vehi cle
    > vehicle.showveh icle(Data(rowno ))
    > end sub
    > =====
    >
    > The Vehicle.showveh icle subroutine is as follows:
    >
    > ====
    > public sub ShowVehicle(Sto ckNo)
    > Dim frm As New ViewVehicleStat us(StockNo)
    >
    > Dim t As New Threading.Threa d(AddressOf frm.dmsShowDial og)
    >
    > 'frm.StockNo = StockNo
    >
    > t.Start()
    >
    > end Sub
    >
    > ====
    >
    > The "dmsShowDia log" subroutine in the form is simply doing a
    > me.showdialog.
    >
    >
    >
    > This all seems to work fine, and when I close the form I see a
    > message such as "The thread '<No Name>' (0x6ec) has exited with code
    > 0 (0x0)." appear in the output window of the development
    > environment.
    >
    > However, the no of handles just keeps increasing - I presumed that
    > the garbage collector should tidy up every now and then, but thats
    > not what I'm seeing.
    >
    > I've not actually duplicated the users issue yet (but I have a high
    > spec machine with masses of memory), but I suspect that this will be
    > the cause of their problem?
    >
    > Any suggestions as to what I've done wrong?
    >
    > Thanks in advance[/color]


    You are creating the Form in the wrong thread. You must create it in the
    thread that you started and that calls Showdialog.

    I don't know if it solve the handles problem. Maybe you don't call Dispose
    on all created resources.

    Armin

    Comment

    • Simon Verona

      #3
      Re: Problem with &quot;handles&q uot; - possible garbage collection issue?

      I'm deliberately creating the form on the new thread to make the call to
      open the form non-blocking. If I didn't create a new thread, then with the
      new form open, the original form would block awaiting it to close.

      Am I doing this wrong? Is there an alternative way to do this?

      I don't use the "dispose" method at all in my code, I presumed that when the
      thread died, the garbage collector would tidy up all the resources used by
      that thread.. Have I got this wrong?

      Regards
      Simon
      "Armin Zingler" <az.nospam@free net.de> wrote in message
      news:eNm9iMTiFH A.3288@TK2MSFTN GP09.phx.gbl...[color=blue]
      > "Simon Verona" <news@aphrodite uk.com> schrieb[color=green]
      >> I have a problem in my application which I believe is due to open
      >> handles.. .
      >>
      >> The symptom that users report is that after they have been using the
      >> application for a while, it will randomly just crash with an
      >> exception report (I've not got the details of the error, but I'm
      >> working on that now!).
      >>
      >> I'm trying to reproduce the circumstances by simulating a typical
      >> batch of user tasks on my pc and monitoring whats happening. I'm
      >> guessing it's some problem with threads/handles or something so I've
      >> opened up the task manager and added all the available columns.
      >>
      >> What I've noticed is that whilst the application is running, the
      >> memory usage keeps increasing, but more worrying, the no of open
      >> handles just keeps going up and up (it's nearly 4000 handles after
      >> running through about 30 tasks).
      >>
      >> What the application is doing is as follows:
      >>
      >> I have a main form showing, which displays a list from a database.
      >>
      >> Then what I'm doing is clicking down the list one by one..
      >>
      >> What this does is to open a form on another thread to stop it
      >> blocking the main window. It does this as follows
      >>
      >> =====
      >> Private sub Click(rowno as int32)
      >> dim vehicle as new dmsvehicle.vehi cle
      >> vehicle.showveh icle(Data(rowno ))
      >> end sub
      >> =====
      >>
      >> The Vehicle.showveh icle subroutine is as follows:
      >>
      >> ====
      >> public sub ShowVehicle(Sto ckNo)
      >> Dim frm As New ViewVehicleStat us(StockNo)
      >>
      >> Dim t As New Threading.Threa d(AddressOf frm.dmsShowDial og)
      >>
      >> 'frm.StockNo = StockNo
      >>
      >> t.Start()
      >>
      >> end Sub
      >>
      >> ====
      >>
      >> The "dmsShowDia log" subroutine in the form is simply doing a
      >> me.showdialog.
      >>
      >>
      >>
      >> This all seems to work fine, and when I close the form I see a
      >> message such as "The thread '<No Name>' (0x6ec) has exited with code
      >> 0 (0x0)." appear in the output window of the development
      >> environment.
      >>
      >> However, the no of handles just keeps increasing - I presumed that
      >> the garbage collector should tidy up every now and then, but thats
      >> not what I'm seeing.
      >>
      >> I've not actually duplicated the users issue yet (but I have a high
      >> spec machine with masses of memory), but I suspect that this will be
      >> the cause of their problem?
      >>
      >> Any suggestions as to what I've done wrong?
      >>
      >> Thanks in advance[/color]
      >
      >
      > You are creating the Form in the wrong thread. You must create it in the
      > thread that you started and that calls Showdialog.
      >
      > I don't know if it solve the handles problem. Maybe you don't call Dispose
      > on all created resources.
      >
      > Armin[/color]


      Comment

      • Anand[MVP]

        #4
        RE: Problem with &quot;handles&q uot; - possible garbage collection issue?

        Why dont you try a form.dispose, when you return from the showdialog and see
        if that solves the handle problem?

        --
        Rgds,
        Anand
        VB.NET MVP



        "Simon Verona" wrote:
        [color=blue]
        > I have a problem in my application which I believe is due to open handles.. .
        >
        > The symptom that users report is that after they have been using the application for a while, it will randomly just crash with an exception report (I've not got the details of the error, but I'm working on that now!).
        >
        > I'm trying to reproduce the circumstances by simulating a typical batch of user tasks on my pc and monitoring whats happening. I'm guessing it's some problem with threads/handles or something so I've opened up the task manager and added all the available columns.
        >
        > What I've noticed is that whilst the application is running, the memory usage keeps increasing, but more worrying, the no of open handles just keeps going up and up (it's nearly 4000 handles after running through about 30 tasks).
        >
        > What the application is doing is as follows:
        >
        > I have a main form showing, which displays a list from a database.
        >
        > Then what I'm doing is clicking down the list one by one..
        >
        > What this does is to open a form on another thread to stop it blocking the main window. It does this as follows
        >
        > =====
        > Private sub Click(rowno as int32)
        > dim vehicle as new dmsvehicle.vehi cle
        > vehicle.showveh icle(Data(rowno ))
        > end sub
        > =====
        >
        > The Vehicle.showveh icle subroutine is as follows:
        >
        > ====
        > public sub ShowVehicle(Sto ckNo)
        > Dim frm As New ViewVehicleStat us(StockNo)
        >
        > Dim t As New Threading.Threa d(AddressOf frm.dmsShowDial og)
        >
        > 'frm.StockNo = StockNo
        >
        > t.Start()
        >
        > end Sub
        >
        > ====
        >
        > The "dmsShowDia log" subroutine in the form is simply doing a me.showdialog.
        >
        >
        >
        > This all seems to work fine, and when I close the form I see a message such as "The thread '<No Name>' (0x6ec) has exited with code 0 (0x0)." appear in the output window of the development environment.
        >
        > However, the no of handles just keeps increasing - I presumed that the garbage collector should tidy up every now and then, but thats not what I'm seeing.
        >
        > I've not actually duplicated the users issue yet (but I have a high spec machine with masses of memory), but I suspect that this will be the cause of their problem?
        >
        > Any suggestions as to what I've done wrong?
        >
        > Thanks in advance
        >
        > Simon
        >
        >
        >
        >
        >
        >[/color]

        Comment

        • Armin Zingler

          #5
          Re: Problem with &quot;handles&q uot; - possible garbage collection issue?

          "Simon Verona" <news@aphrodite uk.com> schrieb[color=blue]
          > I'm deliberately creating the form on the new thread to make the
          > call to open the form non-blocking. If I didn't create a new
          > thread, then with the new form open, the original form would block
          > awaiting it to close.[/color]

          I did not write you shouldn't create another thread.

          What is the reason why you open the Form modally? If you open it modeless
          you don't need another thread and you can still work with the previous form.
          It is usually not necessary to open Forms in different threads. If there's
          work to do that would block the Form(s), you might consider putting only the
          work into a different thread.
          [color=blue]
          > Am I doing this wrong? Is there an alternative way to do this?[/color]

          If you want to open it in another thread, I'd also create it there
          (quick&dirty):

          public sub ShowVehicle(Sto ckNo)
          Dim bla As New viewthread
          bla.start(stock no)
          end Sub

          class viewthread
          private t as thread
          private stockno as stockno

          public sub start(StockNo as ?)
          me.stockno = stockno
          t = new thread(addresso f threadmain)
          t.start
          end sub

          private sub threadmain
          Dim frm As New ViewVehicleStat us(me.StockNo)
          application.run (frm)
          end sub
          end class

          The class is there to be able to pass data (stockno) to the thread.

          [color=blue]
          > I don't use the "dispose" method at all in my code, I presumed that
          > when the thread died, the garbage collector would tidy up all the
          > resources used by that thread.. Have I got this wrong?[/color]

          Yep. Threads, or execution flow in general, has no relation to data and
          memory management.

          Maybe objects from died threads are collected earlier, but I don't think so.
          See also:
          Find official documentation, practical know-how, and expert guidance for builders working and troubleshooting in Microsoft products.


          The m.p.d.framework .clr group is probably the best place to ask for details.


          Armin

          Comment

          • Simon Verona

            #6
            Re: Problem with &quot;handles&q uot; - possible garbage collection issue?

            Ok

            I open the form modally because if I don't - ie use frm.show then the form
            flips open and the immediately disappears again and the thread dies straight
            away.

            However, application.run (frm) seems to do the same thing as opening it
            modally...

            I've re-engineered my code to use the format for creating the thread as you
            describe. It still uses handles each time I open the form using this
            method, though the thread count increases by one as the form opens and then
            decreases again when it is closed... I guess that there are some
            sub-objects somewhere that it believes are not ready to dispose of, though I
            can't think what they might be or where.

            I'll try the other newsgroup as you suggest. Thanks for your help.

            Regards
            Simon
            "Armin Zingler" <az.nospam@free net.de> wrote in message
            news:%233FpYxTi FHA.2916@TK2MSF TNGP14.phx.gbl. ..[color=blue]
            > "Simon Verona" <news@aphrodite uk.com> schrieb[color=green]
            >> I'm deliberately creating the form on the new thread to make the
            >> call to open the form non-blocking. If I didn't create a new
            >> thread, then with the new form open, the original form would block
            >> awaiting it to close.[/color]
            >
            > I did not write you shouldn't create another thread.
            >
            > What is the reason why you open the Form modally? If you open it modeless
            > you don't need another thread and you can still work with the previous
            > form. It is usually not necessary to open Forms in different threads. If
            > there's work to do that would block the Form(s), you might consider
            > putting only the work into a different thread.
            >[color=green]
            >> Am I doing this wrong? Is there an alternative way to do this?[/color]
            >
            > If you want to open it in another thread, I'd also create it there
            > (quick&dirty):
            >
            > public sub ShowVehicle(Sto ckNo)
            > Dim bla As New viewthread
            > bla.start(stock no)
            > end Sub
            >
            > class viewthread
            > private t as thread
            > private stockno as stockno
            >
            > public sub start(StockNo as ?)
            > me.stockno = stockno
            > t = new thread(addresso f threadmain)
            > t.start
            > end sub
            >
            > private sub threadmain
            > Dim frm As New ViewVehicleStat us(me.StockNo)
            > application.run (frm)
            > end sub
            > end class
            >
            > The class is there to be able to pass data (stockno) to the thread.
            >
            >[color=green]
            >> I don't use the "dispose" method at all in my code, I presumed that
            >> when the thread died, the garbage collector would tidy up all the
            >> resources used by that thread.. Have I got this wrong?[/color]
            >
            > Yep. Threads, or execution flow in general, has no relation to data and
            > memory management.
            >
            > Maybe objects from died threads are collected earlier, but I don't think
            > so. See also:
            > http://msdn.microsoft.com/library/en...management.asp
            >
            > The m.p.d.framework .clr group is probably the best place to ask for
            > details.
            >
            >
            > Armin
            >[/color]


            Comment

            • Armin Zingler

              #7
              Re: Problem with &quot;handles&q uot; - possible garbage collection issue?

              "Simon Verona" <news@aphrodite uk.com> schrieb[color=blue]
              > Ok
              >
              > I open the form modally because if I don't - ie use frm.show then
              > the form flips open and the immediately disappears again and the
              > thread dies straight away.
              >
              > However, application.run (frm) seems to do the same thing as opening
              > it modally...[/color]

              No, because you can still use the other Form becaue they are running in
              different threads. Still I am not sure why you open them in different
              threads.
              [color=blue]
              > I've re-engineered my code to use the format for creating the thread
              > as you describe. It still uses handles each time I open the form
              > using this method, though the thread count increases by one as the
              > form opens and then decreases again when it is closed... I
              > guess that there are some sub-objects somewhere that it believes are
              > not ready to dispose of, though I can't think what they might be or
              > where.[/color]

              You should examine your code to see which disposable objects you create.
              After their usage, they should be disposed. If they created native handles
              (those you see in task manager), the handles are destroyed immediatelly. If
              you don't call dispose, they will be destroyed also, but later when GC is
              done.
              [color=blue]
              > I'll try the other newsgroup as you suggest. Thanks for your help.[/color]

              An attempt:

              application.run (frm)
              gc.collect
              gc.waitforpendi ngfinalizers

              just to see what happens. Does it change the behavior you see in the task
              manager?

              Armin

              Comment

              • Jay B. Harlow [MVP - Outlook]

                #8
                Re: Problem with &quot;handles&q uot; - possible garbage collection issue?

                Simon,
                | The symptom that users report is that after they have been using the
                | application for a while, it will randomly just crash with an
                | exception report (I've not got the details of the error, but
                | I'm working on that now!).

                You may want to include one or more Global Exception handlers in your
                program to log any exception reports from "random" crashes.

                Depending on the type of application you are creating, .NET has three
                different global exception handlers.

                For ASP.NET look at:
                System.Web.Http Application.Err or event
                Normally placed in your Global.asax file.

                For console applications look at:
                System.AppDomai n.UnhandledExce ption event
                Use AddHandler in your Sub Main.

                For Windows Forms look at:
                System.Windows. Forms.Applicati on.ThreadExcept ion event
                Use AddHandler in your Sub Main.

                It can be beneficial to combine the above global handlers in your app, as
                well as wrap your Sub Main in a try catch itself.

                There is an article in the June 2004 MSDN Magazine that shows how to
                implement the global exception handling in .NET that explains why & when you
                use multiple of the above handlers...

                Find official documentation, practical know-how, and expert guidance for builders working and troubleshooting in Microsoft products.


                For example: In my Windows Forms apps I would have a handler attached to the
                Application.Thr eadException event, plus a Try/Catch in my Main. The
                Try/Catch in Main only catches exceptions if the constructor of the MainForm
                raises an exception, the Application.Thr eadException handler will catch all
                uncaught exceptions from any form/control event handlers.


                | What this does is to open a form on another thread to
                | stop it blocking the main window. It does this as follows


                Why are using Form.ShowDialog on a second thread?

                I would simply use Form.Show on the main thread.

                Public Sub ShowVehicle(Sto ckNo)

                Dim frm As New ViewVehicleStat us(StockNo)

                frm.Show()

                End Sub

                | However, the no of handles just keeps increasing - I presumed that
                | the garbage collector should tidy up every now and then,
                | but thats not what I'm seeing.

                When the user closes a form opened with Show, it will automatically call
                Dispose when it is closed. When the user closes a Form opened with
                ShowDialog, you need to be certain to call Dispose... Yes the GC will
                eventually, at its descrition, call Finalize on the Form, however this may
                be long after all the handles have been consumed...

                Hope this helps
                Jay

                "Simon Verona" <news@aphrodite uk.com> wrote in message
                news:u2TFzySiFH A.3448@TK2MSFTN GP12.phx.gbl...
                I have a problem in my application which I believe is due to open handles..
                ..

                The symptom that users report is that after they have been using the
                application for a while, it will randomly just crash with an exception
                report (I've not got the details of the error, but I'm working on that
                now!).

                I'm trying to reproduce the circumstances by simulating a typical batch of
                user tasks on my pc and monitoring whats happening. I'm guessing it's some
                problem with threads/handles or something so I've opened up the task manager
                and added all the available columns.

                What I've noticed is that whilst the application is running, the memory
                usage keeps increasing, but more worrying, the no of open handles just keeps
                going up and up (it's nearly 4000 handles after running through about 30
                tasks).

                What the application is doing is as follows:

                I have a main form showing, which displays a list from a database.

                Then what I'm doing is clicking down the list one by one..

                What this does is to open a form on another thread to stop it blocking the
                main window. It does this as follows

                =====
                Private sub Click(rowno as int32)
                dim vehicle as new dmsvehicle.vehi cle
                vehicle.showveh icle(Data(rowno ))
                end sub
                =====

                The Vehicle.showveh icle subroutine is as follows:

                ====
                public sub ShowVehicle(Sto ckNo)
                Dim frm As New ViewVehicleStat us(StockNo)

                Dim t As New Threading.Threa d(AddressOf frm.dmsShowDial og)

                'frm.StockNo = StockNo

                t.Start()

                end Sub

                ====

                The "dmsShowDia log" subroutine in the form is simply doing a me.showdialog.



                This all seems to work fine, and when I close the form I see a message such
                as "The thread '<No Name>' (0x6ec) has exited with code 0 (0x0)." appear in
                the output window of the development environment.

                However, the no of handles just keeps increasing - I presumed that the
                garbage collector should tidy up every now and then, but thats not what I'm
                seeing.

                I've not actually duplicated the users issue yet (but I have a high spec
                machine with masses of memory), but I suspect that this will be the cause of
                their problem?

                Any suggestions as to what I've done wrong?

                Thanks in advance

                Simon







                Comment

                Working...