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. The Lounge
  3. I'm ready to pack it in. I've been outsmarted by .NET's garbage collector (A rant, not a question)

I'm ready to pack it in. I've been outsmarted by .NET's garbage collector (A rant, not a question)

Scheduled Pinned Locked Moved The Lounge
helpannouncementcsharpc++winforms
22 Posts 7 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.
  • honey the codewitchH Offline
    honey the codewitchH Offline
    honey the codewitch
    wrote on last edited by
    #1

    Update: I killed it. It took me the better part of the day to get it right, and then get advanced with how i was using it, and then integrate that into the projects that go with the library but it's done. Woo. Changed the way I was doing interop somewhat, and it's more complicated now but it still works - although perf could be slightly improved (does two HGlobal allocs where it could in theory use one) I sometimes really can't stand managed code. I've got a MIDI callback I'm using while streaming playback, and it's supposed to notify me when the stream needs more data. It forwards that callback to an event off of my MidiStream object Well, it does that fine, and in the console app i wrote it has no problem feeding more data to the stream each time. I had been working on it all night, and finally thought I had it licked. In a windows forms app on the the other hand, it works for awhile, and then randomly crashes because for some reason the delegate that handles the callback has been garbage collected. I have no idea why. It never should have been and doesn't appear to go out of scope anywhere. Worse, I can't even catch the crash in the debugger - it just exits entirely without so much as an error message I'm at a loss, and I can't release with this stability issue. I miss C and C++ right about now. :(

    Real programmers use butterflies

    L S Sander RosselS S 5 Replies Last reply
    0
    • honey the codewitchH honey the codewitch

      Update: I killed it. It took me the better part of the day to get it right, and then get advanced with how i was using it, and then integrate that into the projects that go with the library but it's done. Woo. Changed the way I was doing interop somewhat, and it's more complicated now but it still works - although perf could be slightly improved (does two HGlobal allocs where it could in theory use one) I sometimes really can't stand managed code. I've got a MIDI callback I'm using while streaming playback, and it's supposed to notify me when the stream needs more data. It forwards that callback to an event off of my MidiStream object Well, it does that fine, and in the console app i wrote it has no problem feeding more data to the stream each time. I had been working on it all night, and finally thought I had it licked. In a windows forms app on the the other hand, it works for awhile, and then randomly crashes because for some reason the delegate that handles the callback has been garbage collected. I have no idea why. It never should have been and doesn't appear to go out of scope anywhere. Worse, I can't even catch the crash in the debugger - it just exits entirely without so much as an error message I'm at a loss, and I can't release with this stability issue. I miss C and C++ right about now. :(

      Real programmers use butterflies

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      I think a very known situation for which google gives a lot of hints ;) Btw: Is also PInvoke involved?

      It does not solve my Problem, but it answers my question

      honey the codewitchH 1 Reply Last reply
      0
      • L Lost User

        I think a very known situation for which google gives a lot of hints ;) Btw: Is also PInvoke involved?

        It does not solve my Problem, but it answers my question

        honey the codewitchH Offline
        honey the codewitchH Offline
        honey the codewitch
        wrote on last edited by
        #3

        Yeah it is, but i'm pretty sure my p/invoke calls are correct

        Real programmers use butterflies

        Richard Andrew x64R 1 Reply Last reply
        0
        • honey the codewitchH honey the codewitch

          Update: I killed it. It took me the better part of the day to get it right, and then get advanced with how i was using it, and then integrate that into the projects that go with the library but it's done. Woo. Changed the way I was doing interop somewhat, and it's more complicated now but it still works - although perf could be slightly improved (does two HGlobal allocs where it could in theory use one) I sometimes really can't stand managed code. I've got a MIDI callback I'm using while streaming playback, and it's supposed to notify me when the stream needs more data. It forwards that callback to an event off of my MidiStream object Well, it does that fine, and in the console app i wrote it has no problem feeding more data to the stream each time. I had been working on it all night, and finally thought I had it licked. In a windows forms app on the the other hand, it works for awhile, and then randomly crashes because for some reason the delegate that handles the callback has been garbage collected. I have no idea why. It never should have been and doesn't appear to go out of scope anywhere. Worse, I can't even catch the crash in the debugger - it just exits entirely without so much as an error message I'm at a loss, and I can't release with this stability issue. I miss C and C++ right about now. :(

          Real programmers use butterflies

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          So the error is "A callback was made on a garbage collected delegate of type [whatever]", right?

          honey the codewitch wrote:

          It never should have been and doesn't appear to go out of scope anywhere.

          Well who knows. The GC thinks it's dead, and effectively it's the Source of Truth even when it's wrong. Does it go away if you intentionally leak the delegate? (stick it in a static list)

          1 Reply Last reply
          0
          • honey the codewitchH honey the codewitch

            Yeah it is, but i'm pretty sure my p/invoke calls are correct

            Real programmers use butterflies

            Richard Andrew x64R Offline
            Richard Andrew x64R Offline
            Richard Andrew x64
            wrote on last edited by
            #5

            You are supposed to "pin" the delegate so that the GC doesn't move it around.

            The difficult we do right away... ...the impossible takes slightly longer.

            L honey the codewitchH 3 Replies Last reply
            0
            • Richard Andrew x64R Richard Andrew x64

              You are supposed to "pin" the delegate so that the GC doesn't move it around.

              The difficult we do right away... ...the impossible takes slightly longer.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              Yep :thumbsup:

              It does not solve my Problem, but it answers my question

              1 Reply Last reply
              0
              • Richard Andrew x64R Richard Andrew x64

                You are supposed to "pin" the delegate so that the GC doesn't move it around.

                The difficult we do right away... ...the impossible takes slightly longer.

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                No, though that works. The delegate object being *moved* by the GC doesn't matter, that is handled correctly. But you must prevent it from being collected, and pinning has that as a side effect.

                1 Reply Last reply
                0
                • honey the codewitchH honey the codewitch

                  Update: I killed it. It took me the better part of the day to get it right, and then get advanced with how i was using it, and then integrate that into the projects that go with the library but it's done. Woo. Changed the way I was doing interop somewhat, and it's more complicated now but it still works - although perf could be slightly improved (does two HGlobal allocs where it could in theory use one) I sometimes really can't stand managed code. I've got a MIDI callback I'm using while streaming playback, and it's supposed to notify me when the stream needs more data. It forwards that callback to an event off of my MidiStream object Well, it does that fine, and in the console app i wrote it has no problem feeding more data to the stream each time. I had been working on it all night, and finally thought I had it licked. In a windows forms app on the the other hand, it works for awhile, and then randomly crashes because for some reason the delegate that handles the callback has been garbage collected. I have no idea why. It never should have been and doesn't appear to go out of scope anywhere. Worse, I can't even catch the crash in the debugger - it just exits entirely without so much as an error message I'm at a loss, and I can't release with this stability issue. I miss C and C++ right about now. :(

                  Real programmers use butterflies

                  S Offline
                  S Offline
                  Slacker007
                  wrote on last edited by
                  #8

                  .net - Call has been made on garbage collected delegate in C#? - Stack Overflow[^] first result from Google. hope this helps, not holding my breath. :thumbsup:

                  honey the codewitchH 1 Reply Last reply
                  0
                  • Richard Andrew x64R Richard Andrew x64

                    You are supposed to "pin" the delegate so that the GC doesn't move it around.

                    The difficult we do right away... ...the impossible takes slightly longer.

                    honey the codewitchH Offline
                    honey the codewitchH Offline
                    honey the codewitch
                    wrote on last edited by
                    #9

                    you know what? I thought I had taken care of that but you just reminded me of a spot where I missed it. I use StructureToPtr in what area to package the return as a handle instead of a struct by ref (which is what i need) that way I can pass it around without it being copied. I suppose I could rewrite that as a class, but then i have to pass around the actual structure and break encapsulation. :( Either way, thank you. I think you just led me to the problem.

                    Real programmers use butterflies

                    Greg UtasG 1 Reply Last reply
                    0
                    • S Slacker007

                      .net - Call has been made on garbage collected delegate in C#? - Stack Overflow[^] first result from Google. hope this helps, not holding my breath. :thumbsup:

                      honey the codewitchH Offline
                      honey the codewitchH Offline
                      honey the codewitch
                      wrote on last edited by
                      #10

                      it didn't help but another commenter reminded me of something i did that could have caused it. I have to retool some code

                      Real programmers use butterflies

                      1 Reply Last reply
                      0
                      • honey the codewitchH honey the codewitch

                        you know what? I thought I had taken care of that but you just reminded me of a spot where I missed it. I use StructureToPtr in what area to package the return as a handle instead of a struct by ref (which is what i need) that way I can pass it around without it being copied. I suppose I could rewrite that as a class, but then i have to pass around the actual structure and break encapsulation. :( Either way, thank you. I think you just led me to the problem.

                        Real programmers use butterflies

                        Greg UtasG Offline
                        Greg UtasG Offline
                        Greg Utas
                        wrote on last edited by
                        #11

                        I hope you weren't too far along in porting the whole thing to C++. :-D

                        Robust Services Core | Software Techniques for Lemmings | Articles

                        <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                        <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                        honey the codewitchH 1 Reply Last reply
                        0
                        • Greg UtasG Greg Utas

                          I hope you weren't too far along in porting the whole thing to C++. :-D

                          Robust Services Core | Software Techniques for Lemmings | Articles

                          honey the codewitchH Offline
                          honey the codewitchH Offline
                          honey the codewitch
                          wrote on last edited by
                          #12

                          hah, nah and I got it working. I still have a memory leak but it should go away when I refactor

                          Real programmers use butterflies

                          1 Reply Last reply
                          0
                          • honey the codewitchH honey the codewitch

                            Update: I killed it. It took me the better part of the day to get it right, and then get advanced with how i was using it, and then integrate that into the projects that go with the library but it's done. Woo. Changed the way I was doing interop somewhat, and it's more complicated now but it still works - although perf could be slightly improved (does two HGlobal allocs where it could in theory use one) I sometimes really can't stand managed code. I've got a MIDI callback I'm using while streaming playback, and it's supposed to notify me when the stream needs more data. It forwards that callback to an event off of my MidiStream object Well, it does that fine, and in the console app i wrote it has no problem feeding more data to the stream each time. I had been working on it all night, and finally thought I had it licked. In a windows forms app on the the other hand, it works for awhile, and then randomly crashes because for some reason the delegate that handles the callback has been garbage collected. I have no idea why. It never should have been and doesn't appear to go out of scope anywhere. Worse, I can't even catch the crash in the debugger - it just exits entirely without so much as an error message I'm at a loss, and I can't release with this stability issue. I miss C and C++ right about now. :(

                            Real programmers use butterflies

                            Sander RosselS Offline
                            Sander RosselS Offline
                            Sander Rossel
                            wrote on last edited by
                            #13

                            I have the same-ish problem! :~ It's not garbage collected, but disposed. I'm reading some files and then process them. The processing takes a while, around 45 minutes. For the first 30 minutes everything goes well, but after 30 minutes I suddenly get an ObjectDisposedException from my Entity Framework Core context :~ I'm not disposing it and if I did, I'd expect it to blow well before 30 minutes since it's a loop. I'm not aware of any automatic disposes, but 30 minutes sounds like some timeout setting. While writing this I'm thinking of something that could be the problem... :D

                            Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly

                            honey the codewitchH Greg UtasG 2 Replies Last reply
                            0
                            • Sander RosselS Sander Rossel

                              I have the same-ish problem! :~ It's not garbage collected, but disposed. I'm reading some files and then process them. The processing takes a while, around 45 minutes. For the first 30 minutes everything goes well, but after 30 minutes I suddenly get an ObjectDisposedException from my Entity Framework Core context :~ I'm not disposing it and if I did, I'd expect it to blow well before 30 minutes since it's a loop. I'm not aware of any automatic disposes, but 30 minutes sounds like some timeout setting. While writing this I'm thinking of something that could be the problem... :D

                              Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly

                              honey the codewitchH Offline
                              honey the codewitchH Offline
                              honey the codewitch
                              wrote on last edited by
                              #14

                              Ouch! Good luck!

                              Real programmers use butterflies

                              1 Reply Last reply
                              0
                              • Sander RosselS Sander Rossel

                                I have the same-ish problem! :~ It's not garbage collected, but disposed. I'm reading some files and then process them. The processing takes a while, around 45 minutes. For the first 30 minutes everything goes well, but after 30 minutes I suddenly get an ObjectDisposedException from my Entity Framework Core context :~ I'm not disposing it and if I did, I'd expect it to blow well before 30 minutes since it's a loop. I'm not aware of any automatic disposes, but 30 minutes sounds like some timeout setting. While writing this I'm thinking of something that could be the problem... :D

                                Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly

                                Greg UtasG Offline
                                Greg UtasG Offline
                                Greg Utas
                                wrote on last edited by
                                #15

                                Sander Rossel wrote:

                                While writing this I'm thinking of something that could be the problem...

                                Isn't your rubber duck listening today? :laugh:

                                Robust Services Core | Software Techniques for Lemmings | Articles

                                <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                                <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                                Sander RosselS 1 Reply Last reply
                                0
                                • Greg UtasG Greg Utas

                                  Sander Rossel wrote:

                                  While writing this I'm thinking of something that could be the problem...

                                  Isn't your rubber duck listening today? :laugh:

                                  Robust Services Core | Software Techniques for Lemmings | Articles

                                  Sander RosselS Offline
                                  Sander RosselS Offline
                                  Sander Rossel
                                  wrote on last edited by
                                  #16

                                  A friend once asked the same, but made a typo. He ended up asked about my rubber d... Well, just check the letter next to "U" :laugh: Since then I can't read or hear "rubber duck" without thinking about it :~

                                  Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly

                                  Greg UtasG 1 Reply Last reply
                                  0
                                  • Sander RosselS Sander Rossel

                                    A friend once asked the same, but made a typo. He ended up asked about my rubber d... Well, just check the letter next to "U" :laugh: Since then I can't read or hear "rubber duck" without thinking about it :~

                                    Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly

                                    Greg UtasG Offline
                                    Greg UtasG Offline
                                    Greg Utas
                                    wrote on last edited by
                                    #17

                                    If that's what you do to your rubber duck, no wonder it isn't listening. :laugh:

                                    Robust Services Core | Software Techniques for Lemmings | Articles

                                    <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                                    <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                                    1 Reply Last reply
                                    0
                                    • honey the codewitchH honey the codewitch

                                      Update: I killed it. It took me the better part of the day to get it right, and then get advanced with how i was using it, and then integrate that into the projects that go with the library but it's done. Woo. Changed the way I was doing interop somewhat, and it's more complicated now but it still works - although perf could be slightly improved (does two HGlobal allocs where it could in theory use one) I sometimes really can't stand managed code. I've got a MIDI callback I'm using while streaming playback, and it's supposed to notify me when the stream needs more data. It forwards that callback to an event off of my MidiStream object Well, it does that fine, and in the console app i wrote it has no problem feeding more data to the stream each time. I had been working on it all night, and finally thought I had it licked. In a windows forms app on the the other hand, it works for awhile, and then randomly crashes because for some reason the delegate that handles the callback has been garbage collected. I have no idea why. It never should have been and doesn't appear to go out of scope anywhere. Worse, I can't even catch the crash in the debugger - it just exits entirely without so much as an error message I'm at a loss, and I can't release with this stability issue. I miss C and C++ right about now. :(

                                      Real programmers use butterflies

                                      S Offline
                                      S Offline
                                      Stuart Dootson
                                      wrote on last edited by
                                      #18

                                      We had similar(-ish, but the opposite way round) problems with the JVM's GC, while interfacing it to a COM component we needed to use. Instead of releasing objects before we wanted, the GC was holding onto COM reference wrapper objects long after their lifetime was over (because the objects were small, so the GC wasn't experiencing any memory pressure). This meant that the actual COM objects weren't being released, so were exhausting memory outside of the JVM :-/ GC works fine for memory allocated and used solely within the containing virtual machine environment - anything slightly more complex, and you're dicing with death (of your hopes and dreams).

                                      Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                                      honey the codewitchH 1 Reply Last reply
                                      0
                                      • S Stuart Dootson

                                        We had similar(-ish, but the opposite way round) problems with the JVM's GC, while interfacing it to a COM component we needed to use. Instead of releasing objects before we wanted, the GC was holding onto COM reference wrapper objects long after their lifetime was over (because the objects were small, so the GC wasn't experiencing any memory pressure). This meant that the actual COM objects weren't being released, so were exhausting memory outside of the JVM :-/ GC works fine for memory allocated and used solely within the containing virtual machine environment - anything slightly more complex, and you're dicing with death (of your hopes and dreams).

                                        Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                                        honey the codewitchH Offline
                                        honey the codewitchH Offline
                                        honey the codewitch
                                        wrote on last edited by
                                        #19

                                        I've run into the same problem as you before. The solution is to marshal the objects as IntPtrs, and manually release them when you're done, if I recall correctly. That way you control the lifetime explicitly. It makes things easier. I solved the problem with my MIDI code in the OP, and then improved on it several times :-D to make it more efficient and easier to read the code. Now in my entire streaming codebase i only have one win32 global heap allocation that happens once you open a device, until you close it. I've taken to marshalling all structs as ref (struct) except for a very complicated vector of variable length structs which I have to mangle manually. So it's golden now, and even mostly easier to read and maintain when I'm done. Cool beans.

                                        Real programmers use butterflies

                                        S 1 Reply Last reply
                                        0
                                        • honey the codewitchH honey the codewitch

                                          I've run into the same problem as you before. The solution is to marshal the objects as IntPtrs, and manually release them when you're done, if I recall correctly. That way you control the lifetime explicitly. It makes things easier. I solved the problem with my MIDI code in the OP, and then improved on it several times :-D to make it more efficient and easier to read the code. Now in my entire streaming codebase i only have one win32 global heap allocation that happens once you open a device, until you close it. I've taken to marshalling all structs as ref (struct) except for a very complicated vector of variable length structs which I have to mangle manually. So it's golden now, and even mostly easier to read and maintain when I'm done. Cool beans.

                                          Real programmers use butterflies

                                          S Offline
                                          S Offline
                                          Stuart Dootson
                                          wrote on last edited by
                                          #20

                                          I did it slightly differently - I wrote a class to implement something like an [Objective-C autorelease pool](https://www.informit.com/articles/article.aspx?p=1806938&seqNum=7), which our COM object wrappers added themselves to automatically. The pool was released in a [`finally` block](https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html) & that would release all the COM objects that had been allocated and finished - something like this... ```java AutoReleasePool.createPool(); // Push a new pool onto the stack of pools try { ... Do stuff ... } finally { AutoReleasePool.releasePool(); // Pop the top pool in the stack , releasing all the objects in it } ```

                                          Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                                          honey the codewitchH 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