This is a bit off topic question, but since some folks here know more than me about garbage collection, I am looking for some insights.

This is a bit off topic question, but since some folks here know more than me about garbage collection, I am looking for some insights.

What I want to know is when your app consumes more and more memory to the point it crashes, but calling System.gc() (Java) or manual triggering of GC through debugger cleans up the whole mess, is it your code that is having a leak or it is just buggy GC?

For instance app at startup consumes about 24MB, while working that amount rises to 500MB (and it should not pass 45MB) and after triggering GC from debugger allocated memory drops to 24MB.
http://stackoverflow.com/q/30776779/4267244

Comments

  1. I'm not an expert on GCs, but I thought it was normal for memory issues to trigger a garbage collection. So if you get OOM errors and the GC was never called, then that seems to me like either at best bad system&GC design or at worst a bug.

    ReplyDelete
  2. Not sure about Java, but in .NET the GC is triggered when the application is Idle (something that does not happen if you have intensive processing), or when the memory is 100% consumed. I will let you judge for yourself how good the design is. However most of the customers/developers calling with memory issues, and crashes due to out of resources in their .NET applications, and after I tell them to add manual call to GC it is all fixed. In my opinion, the GC design as implemented in .NET is a joke to say the least. Java may suffer from the same.

    ReplyDelete
  3. True confession: I know nothing about GC but I came across some code at one time I named TrimAppMemorySize which I call frequently when the program is quiescent and consumed memory remains very low. Now if I could find something that would flush page faults.

    procedure TrimAppMemorySize;
    var
      MainHandle : THandle;
    begin
      try
        MainHandle := OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessID);
        SetProcessWorkingSetSize(MainHandle, $FFFFFFFF, $FFFFFFFF);
        CloseHandle(MainHandle);
      except
      end;
    end;

    ReplyDelete
  4. Boian Mitov Your post gave me some ideas, so I tried giving system more than enough idle time to clean up (several minutes, when app memory consumption was at 450MB out of 512MB available), but no luck, CPU usage is at 0, and GC is not triggered. It looks like Android/Java GC is no better than the .NET one.

    Everyone keep saying that you should not mess with GC and leave the system alone to do the job, but what to do when it completely fails. I have managed to reproduce buggy behavior on only one from five different devices I have tested, but one is more than enough. There is no way to tell when and where GC will fail, and it seems that only way to deal with it is to manually trigger GC when I think it is needed.

    ReplyDelete
  5. Dalija Prasnikar The GC is nothing short of joke or myth. In so many years, I am yet to see a .NET or Java application that behaves even remotely stable to say the least. Eclipse and Visual Studio are probably the poster children showing how bad the GC really is. I am also yet to see application, where you don't have to manually call the GC, and don't even start me on the manual Dispose pattern, that brigs it all into the dark ages of the computing industry, rendering both Java and .NET in essence at the level of C in terms of resource management. In short, if you want troubles, and memory leaks, and out of resource crashes, please go for GC based languages, and shoot yourself in the foot... In those respects they are equally bad as C was in the old days. While I love memory management when done right, and I use it all the time, the .NET and Java GC implementations are something I stay as far away as I can.

    ReplyDelete
  6. Boian Mitov I have never wasted so much time hunting down memory issues in Delphi (or any other manual memory management or ARC based language) like I had with GC in Java on Android.

    GC is maybe nice for newbies that are barely capable of writing down few lines of code, but when you start writing real applications it is pure nightmare.

    Not to mention that everything in Java is object so you have to write ridiculous code just to avoid excessive memory allocations/de-allocations.

    ReplyDelete
  7. Dalija Prasnikar 100% agree... I have the same experience, and I have customers ( users of our .NET libraries ) calling weekly with GC issues in their code. I spend sometime more time teaching people how to work around the GC mess than writing code :-( . In my opinion, trying to write complex software with any of those 2 GC implementation, is a painful suicide attempt.

    ReplyDelete
  8. Boian Mitov I have no .NET experience, so I thought that my first (and second) bad impressions of GC systems are mainly influenced by dealing with it on devices with seriously limited resources. Now you are saying that GC is equally bad everywhere...

    ReplyDelete
  9. Dalija Prasnikar I am talking only about the .NET and Java implementations. Don't get me wrong, I am for certain forms of GC, I use my own implementations, and I have proposed others, and I love the ARC, but not the .NET and Java versions. They have copied from each other, with all the design bugs in them. That's the problem.

    ReplyDelete
  10. Boian Mitov I am quite fond of ARC, too. But, I think that is as far as my love for any automatic memory management will ever go :)

    I am not that familiar with GC systems, so maybe they are not all bad. I will take your word for it.

    ReplyDelete
  11. Dalija Prasnikar As with anything in life... there are good and bad GC systems ;-) . It just happens that Java and .NET have the bad ones...

    ReplyDelete
  12. Patrick Hughes , I have come across the code before
    and funny enough I am just going to try it out just before reading that you use it,,...as I have discovered my program gets into trouble with available memory after a period of time

    ReplyDelete
  13. Brian Hamilton Absolutely normal behavior for GC code ;-) . In the old days, I had a Java Applet that used to crash the system :-D
    I mean it was not written by me, but was in one of the sites I used to go. If you leave the site for few H opened, the system used to crash...

    ReplyDelete
  14. GC are a real pita for server applications running all day long. You need to restart them on a regular basis... Whereas a Delphi server could run for months and use little memory.
    I have seen java and c# experts doing amazing things just to circumvent the GC system....

    ReplyDelete
  15. A. Bouchez "I have seen java and c# experts doing amazing things just to circumvent the GC system...."
    Yeah... me too... and the GC was supposed to make life easier :-D . Best joke ever...!

    ReplyDelete
  16. So is this a bug on your particular physical handset/phone/tablet?

    ReplyDelete
  17. Warren Postma Yes. In fact I have two same model devices one with API 16 that works fine and another with API 19 that does not. Also other devices I have with API 19 work fine.

    ReplyDelete
  18. This gives me SUCH a bad feeling about working on Android as a platform.

    ReplyDelete
  19. Warren Postma On the other hand, any platform, tool, language I have ever worked with had fair number of WTF issues. Most problematic part is getting to know them and to how to deal with them.

    ReplyDelete
  20. Yeah. Garbage collection, coming from a Delphi background, is just one of my Bugaboos.  I believe that the ARC model (automatic reference counting as done in iOS using Objective-C or Swift, under the hood, it's clang/llvm)is inherently superior (more predictable, fewer traps) than GC.  In ARC, you need Weak References to prevent cycles. In GC you also need Weak References, but in ARC you can verify you have no cycles, I have no idea other than waiting for it to crash, how to find the same out in a GC environment.

    ReplyDelete
  21. Warren Postma The thing I most dislike about GC is its indeterminate nature. 

    You don't know when it will kick in, and when it does it can create visible lags in software. With manual memory management and ARC time cost of allocation/deallocation is fixed and consistent.

    Not to mention that overall memory needed for GC apps is greater than memory needed for manual/ARC managed apps.

    ReplyDelete
  22. I once wrote a Java-server app that leaked memory even though we were really careful to avoid it. We "solved" it by exiting process when last user logged out, then restart using batchfile (start: java... goto start). Worked fine :-)

    ReplyDelete
  23. Ville Krumlinde So in this case, running the Java server as a good old plain cgi may make sense. Welcome in the 21th century.  ;)

    ReplyDelete

Post a Comment