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

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 these runtimes , Why is there a memory leak?

Author: Maniero, 2018-06-21

2 answers

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 him, all the other objects to which he refers.

That case there until it is quite obvious. However, there are several ways subtle and not at all obvious to achieve similar results that can arise 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.

 9
Author: Victor Stafusa, 2018-06-21 01:53:51

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

It is not so simple to answer the question specifically because not a specific problem, but it is easy to answer in a generalized way, and so it does not matter if it is in the CLR or the JVM.

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

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

Has several situations that are complicated to manage.

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

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

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

Mistakes

The answer (quoted in comment by hkotsubo) from the so is bad. First because it ignores the Undecidable Problemand second because it speaks of memory leak something that makes everything in heap a memory leak as I said, even so the answer does not address the problem by the definition you provided.

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

Specific example

I I have not heard of leakage in Oracle.DataAccess.dll, which is something of the .NET and not JVM and it must be a programming error of who made this code within the possibilities that I cited, or it is an error of use of the classes of this module that does not allow the release, then the error is not his and

To reply to Jefferson Quesado (comment):

One of the reasons for the existence of the tracing garbage collector is precisely to avoid cyclic references preventing the release. The algorithm of tracer collectors check which are the active references, usually start with the roots that are the references contained in the registers and in the stack, eventually in static area if this is possible in the language/environment, then go to heap which is where the GC acts.

The GC of JVM and CLR is compactor and generational. This means that it does not remove garbage effectively, it only preserves what is still alive, so if it has a reference for it, the object will be copied to another generation. Objects that are not identified as having at least one reference are abandoned in area that will be reused later, or released (usually not).

In this Victor example if the method is running during collection obviously has a reference in the stack, then the list will be preserved. If the method is no longer running, it does not have a reference to the list, so it will not be copied to the next generation and at the end of the collection a area where she 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 reference it, you don't even have to 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 to itself.

Of course if you identify that somewhere else has a reference to the list, it will be copied and then when it sees that the object, whose temporary alias in this example is x, it will know that the list needs to be copied, but it already knew before. To say that the object has one, two or a thousand references for it gives anyway, 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 copied object for the new generation.

Understand that an object that is within a list or other structure can be copied individually if it has 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 for references within a framework, C# does.

Remembering that reference count mechanism ( reference count ) is a GC and it allows leakage by circular references, unless in a very sophisticated mechanism with problems to the point of needing a tracing GC of backup or even switching completely to cases that may have circular references, especially those that are not direct and in graphs, which are quite complicated to detect, when possible.

 7
Author: Maniero, 2020-07-23 13:20:46