Does the garbage collector really exist? Why then is there a memory leak in runtimes that use it?

Asked

Viewed 172 times

2

I’ve heard of memory leakage in Oracle.DataAccess.dll and in large applications developed for runtimes with garbage collector.

If the garbage collector exists in those runtimes, why there is memory leakage?

  • 1

    There are some reasons. In Java <= 7, some things were allocated in the perm, such as some special strings and classes, and the perm is beyond the GC

  • 5

    Another thing is that any collector has limits. There is an algorithm that determines/marks what can be collected and what cannot, because it is in use. If your code doesn’t make clear what no longer needs to be used, you’ll be left with accumulated garbage (= memory Leak).

  • 3

    https://stackoverflow.com/a/10619408

2 answers

9


Why the garbage collector only collects references that are no longer accessible. However, it is still possible to have memory leaks through accessible references. For example:

 public class VazadorDeMemoria {
     private static final List<Object> monteDeLixo = new ArrayList<>();

     public static void fazerComQueObjetoNuncaPossaSerColetado(Object x) {
          monteDeLixo.add(x);
     }
 }

Any object that is passed as a parameter to this method there, will be stuck in memory indefinitely and can never be collected as garbage. And with it, all the other objects to which he refers.

This case is pretty obvious. However, there are a number of subtle and not obvious ways to achieve similar results that can happen accidentally when you are programming. What happens is that somehow, the garbage is kept in memory but there are still accessible references pointing to it, and therefore can not be collected.

  • I always wondered how garbage collectors do with circular references... like ArrayList<ArrayList<Object>> x = new ArrayList<>(); x.add(x); In this case, when exiting the method, x will have a self-reference, but will no longer be in any scope and therefore should be collected. I particularly don’t know how the GC handles these cases, I just have faith that it will work

  • 3

    @Jeffersonquesado Modern garbage collectors can manage with circular references (the simplest algorithm of this type is to mark all objects that are accessible by following the references and then collect all those that have not been marked). However, references kept accessible even if useless, there is no way.

7

Garbage collectors collect garbage, not other things. Any object in the heap that has a reference to it is not garbage, has no reason to collect.

It’s not so simple to answer the question specifically because it’s not a specific problem, but it’s easy to answer generalized, and so it doesn’t matter if it’s in CLR or JVM.

Defining what is memory leakage is tricky. If you consider that objects are not destroyed after they are no longer referenced, you leak all the time... temporarily. It may not be leaking at all, so even an object that survives throughout the execution of the application may not be a leak if it is in use, even if inadvertently.

And that’s important, the GC works when the code is doing the right thing. GC is about automatically managing memory, not about doing everything right in the code. If you leave something in use that you shouldn’t, it’s not leaking memory, it’s another mistake. Leak, for me, is when the intention is to release the memory and does not.

There are several situations that are complicated to manage.

Note that the Garbage collector only releases memory of objects managed by it. So anything that is allocated without its use, and it is possible to do this in JVM, but currently not directly in Java, and in CLR even by C# in context unsafe, can leak in these cases if manual memory treatment is not well done.

We can also talk about features not managed by the application, such as a file or database. Although they occupy memory of the Java application or . NET is not directly managed memory. If the feature is not released by your application by the Dispose project standard or fully manual, it will leak.

There are cases that can occur leakage by the way one implements some standard. An example is events that if you do not remove subscribers correctly can keep reference to an object that is no longer needed, which prevents its removal even if it is without function.

Mistakes

To OS response (quoted in commentary by hkotsubo) is bad. First because ignores the undecidable problem and second because it speaks in memory leak something that makes everything in the heap a memory leak as I said, yet the answer does not address the problem by the definition it provided.

Depending on the definition, it is not memory leakage if it has a reference to the object, it is a programming error that does not allow the release of memory because the object is in use. Of course, there is a definition that considers it a leak. I don’t know if Victor’s example is a leak because it might be the intention. The object is in use, I don’t see any error, but if it is of intention, not of programming. The object stays until it is in the list, and can leave at any time. Generally I would say that it is not a leak.

Specific example

I haven’t heard of leaking in Oracle.DataAccess.dll, what is something of . NET and not JVM and it must be a programming error of who made this code within the possibilities that I mentioned, or it is an error of use of the classes of this module that does not allow the release, then the error is not of him and yes of who uses it.

To reply to Jefferson Quesado (comment):

One of the reasons why tracing Garbage collector is precisely to avoid cyclical references to prevent release. The tracer collectors' algorithm checks which are the active references, usually starting with the roots that are the references contained in the registers and the stack, eventually in static area if this is possible in language/environment, then goes pro heap which is where the GC acts.

The GC of the JVM and the CLR is a compactor and generational. This means that it doesn’t remove junk effectively, it just preserves what’s still alive, so if you have a reference to it, the object will be copied to another generation. Objects that are not identified as having at least one reference are abandoned in an area that will be reused later, or released (usually not).

In this example of Victor if the method is running during the collection it obviously has a reference on the stack, then the list will be preserved. If the method is no longer running, there is no reference to the list, so it will not be copied to the next generation and at the end of the collection the area where it was will be released for use, which in practice is a destruction.

If the list is not referenced in the roots or other structures in the heap that refer to it, there is no reason to even check if it has references to other objects, whether self-referenced or not. The object within it is not evaluated to know if it is a reference to something else, much less if it is for itself.

Of course if you identify that somewhere else has a reference to the list, it will be copied and then when you see that the object, whose temporary alias in this example is the x, She’ll know the list needs to be copied, but he knew it before. Say that the object has one, two or a thousand references to it gives in it, only one copy will be made (technically it is a move because the original will be abandoned), the references will be updated to the new address of the object copied to the new generation.

Understand that an object that is within a list or other structure can be copied individually if you have a reference to it somewhere else, this does not mean that the list needs to be copied. Unless mistaken, Java does not allow this, there can be no reference to references within a structure, C# yes.

Recalling which reference counting mechanism (Reference Count) is a GC and it allows leakage by circular references, except in a very sophisticated mechanism with its own problems that comes to the point of needing a tracing GC of backup or even the change altogether for cases that may have circular references, especially those that are not direct and in graphs, which are quite complicated to be detected, when it is possible.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.