Is there a JVM lacking garbage collector? - java

There was a comment in the question calling-system-gc-explicitly stating that "You can not "force" a generic JVM to do garbage collection because a garbage collector is not actually required by the JVM spec.". My question is if there's such a JVM (and how and where does it get used, if so).

For instance, JavaCard's JVM lacked garbage collection until v3.

Garbage collection (if you ignore weak and soft references) is roughly a simulation of having infinite memory, at least for objects that are unreachable. If an object gets garbage collected in the woods and no code can reach it, did it make a sound?
In practice, JVMs without collectors would be few and far between because in practice memory is limited. About the only places I can think of where a JVM without a GC would be useful would be a research/learning JVM, or a JVM used only for very short-lived processes (where you know you'll destroy the entire JVM before it consumes too much memory).

Related

How substratevm gc itself?

In graalvm project, gc is written in java in substratevm. What makes me curious is how to manage the memory of a garbage collector written in a language with gc.
If he manages his own memory by himself, it may cause an infinite loop. Here I assume that the garbage collector includes the functions of memory allocation and recovery, and give an example.
For example: My code is a garbage collector-> I need to create an object and allocate memory-> I called the garbage collector (myself)-> I need to create an object and allocate memory > I called the garbage collector (myself) ......
How does it solve infinite loop problems? My idea is to use a lightweight garbage collector written in an additional local language (like C language) to run itself (garbage collector written in java). Although substratevm seems to be compiled into a local executable binary file in native-image, I think the problem still exists.
SubstrateVM GC is written in a subset of Java that has a few restrictions. One of them is that GC code never allocates memory on the Java heap -- see com.oracle.svm.core.heap.RestrictHeapAccess.NO_ALLOCATION. That makes sense as GC is often started in response to the heap being full, so it would not be able to allocate anything anyway. Instead it requests memory chunks directly from the OS using mmap and the like -- see CommittedMemoryProvider and VirtualMemoryProvider classes

Garbage collector don't run when object is referenced.Which object?

As there are so many objects being created for a particular class some of which could be referenced and some can be anonymously lying in the heap and hence elgible for garbage collection . So is the presence of even one non referenced object in the heap is enough for garbage collector to run or is there any other criteria to assure the garbage collector is executed.
Thanks
Jayendra
we don't know when GC get executed, it depend on lots of things e.g. Type of GC. Also you can recommend to VM to launch GC by doing System.gc(). But again it is just a recommendation
GC on an object is, for typical reference implementations of the JVM, completely non-deterministic. There is no way to guarantee when, or even if, the GC will be run, never mind if it will result in a particular object reference being released (and its corresponding finalizer called.) This is regardless of the state of this particular object.
As pointed out in comments, System.gc() is merely a hint or request. In a great many cases it will result in a full GC. But consider gathering a heap dump usually results in 2-3 calls to System.gc() before the dump is generated, mostly as a way to improve the chances it actually happens.
There are experimental VMs that offer various implementations of real-time guarantees where some of this is not true.

When does garbage collection work in java?

I knew that there are a lot of articles about java garbage collection but after searching I don't know exactly "when dose the garbage collection run in a java application?(when the application restart or while it still running)".
Garbage Collector is a dameon thread. A dameon thread runs behind the application. It is started by JVM. The
thread stops when all non-dameon threads stop.
The JVM controls the Garbage Collector; it decides when to run the Garbage Collector. JVM runs
the Garbage Collector when it realizes that the memory is running low. The behavior of GC can
be tuned by passing parameters to JVM.
One can request the Garbage Collection to happen from
within the java program but there is no guarantee that this request will be taken care of by
jvm.Check How to force garbage collection in Java?
Learn More ..
Garbage collection runs regularly alongside the program. It is part of the JVM.
When exactly does it run though? Well, that's unpredictable, version-dependent, and should be treated as if it could run at any time.
When a variable goes out of scope, the application tells the JVM it's done with that piece of memory. Then, when the garbage collector runs it will free those resources for the OS to use.
For example
String capitalizeAll(String s) {
char[] chars = s.toCharArray();
for(int i = 0; i < chars.length; i++)
chars[i] -= 32;
return new String(chars);
}
As soon as the method returns, the char[] chars allocated within the method will go out of scope. The program tells the JVM it's done with those resources and next time GC runs they will be freed.
Interesting stuff though, the JVM takes into account how much the app has told it is ready to be collected. That means that if your app does a lot of unnecessary copying or boxing, JVM will run often and cause your app to take a performance hit.
This is mostly implementation-specific.
The most primitive type of garbage collector, the serial GC will be triggered when it fails to find sufficient free space during an allocation (with generational GCs this usually means the young generation is full). It then suspends the entire JVM by triggering a safepoint on mutator threads and does its work on a single thread, this is called a "stop the world pause"
In this case you can say that GCs can be caused by any allocation.
On top of that some GCs may also do background work concurrently to mutators, such as Hotspot's CMS. But it still needs stop the world pauses for some work, they just tend to be shorter than in the serial GC.
For CMS it's still triggered by allocations but also does some of its work on background thread(s).
Azul Zing's concurrent compacting collector also does - as its name says - concurrent collecting on dedicated threads more or less all the time. It still needs cooperation from the mutator threads but does so without STW pauses.
So this case one could say that the GC is running all the time in the background and does a little work in the foreground.
There are other collectors out there, so this isn't a comprehensive overview. But in general it's an implementation detail, subject to change and not something one should rely on. Some GCs even ignore System.gc() by default because it would mess up their heuristics.
This is from Kathy Sierra and Bert Bates' book SCJP Study Guide:
"The garbage collector is under the control of the JVM. The JVM decides when to
run the garbage collector. From within your Java program, you can ask the JVM to
run the garbage collector, but there are no guarantees, under any circumstances, that the JVM will comply. Left to its own devices, the JVM will typically run the garbage collector when it senses that memory is running low. Experience indicates that when your Java program makes a request for garbage collection, the JVM will usually grant your request in short order, but there are no guarantees. Just when you think you can count on it, the JVM will decide to ignore your request."

Java - Why forced garbage collection doesn't release memory

I am generating a large data structure and write it to hard disk. Afterwards I want to get rid of the object, to reduce the memory consumption. My problem is that after I had forced a garbage collection the amount of used memory is at least as high as it was before garbage collection. I have added a minimal working example what I am doing.
DataStructure data = new DateStructure();
data.generateStructure(pathToData);
Writer.writeData(data);
WeakReference<Object> ref = new WeakReference<Object>(data);
data = null;
while (ref.get() != null) {
System.gc();
}
The code should force a garbage collection on the data object as it is recommended in thread:
Forcing Garbage Collection in Java?
I know this garbage collection does guarantee the deletion of the data object, but in the past I was more successful by using the garbage collection as described at the link as using simply System.gc().
Maybe someone has an answer whats the best way to get rid of large objects.
It seems that this is premature optimization (or rather an illusion of it). System.gc(); is not guaranteed to force a garbage collection. What you are doing here is busy waiting for some non-guaranteed gc to happen. But if the heap does not get filled up the JVM might not start a garbage collection at all.
I think that you should start thinking about this problem when you stress test your application and you can identify this part as a bottleneck.
So in a nutshell you can't really force a gc and this is intentional. The JVM will know when and how to free up space. I think that if you clear your references and call System.gc(); you can move on without caring about whether it gets cleaned up or not. You may read the Official documentation about how to fine-tune the garbage collector. You should rather be using some GC tuning according to the documentation than asking java to GC from your code.
Just a sidenote: the JVM will expand some of the heap's generations if the need arises. As far as I know there is a configuration option where you can set some percentage when the JVM will contract a generation. Use MinHeapFreeRatio/MaxHeapFreeRatio if you don't want Java to reserve memory which it does not need.
This idiom is broken for a whole range of reasons, here are some:
System.gc() doesn't force anything; it is just a hint to the garbage collector;
there is no guarantee when a weak reference will be cleared. The spec says "Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable". When that happens, it is up to the implementation;
even after the weak reference is cleared, there is no telling when its referent's memory will actually be reclaimed. The only thing you know at that point is that the object has transitioned from "weakly reachable" to "finalizable". It may even be resurrected from the finalizer.
From my experience, just doing System.gc a fixed number of times, for example three, with delays between them (your GC could be ConcurrentMarkSweep) in the range of half-second to second, gives much stabler results than these supposedly "smart" approaches.
A final note: never use System.gc in production code. It is almost impossible to make it bring any value to your project. I use it only for microbenchmarking.
UPDATE
In the comments you provide a key piece of information which is not in your question: you are interested in reducing the total heap size (Runtime#totalMemory) after you are done with your object, and not just the heap occupancy (Runtime#totalMemory-Runtime#freeMemory). This is completely outside of programmatic control and on certain JVM implementations it never happens: once the heap has increased, the memory is never released back to the operating system.

java - garbage collection

Why the method call System.gc() doesn't guarantee that the Garbage Collector algorithm will run at that moment? Why it cannot certainly reclaim all unused object's memory whenever it is invoked ?
Forcing object destruction is sign of bad coding so Java might wanted to avoid developers from getting addicted to it.
If Java gives you freedom of forcing of object destruction, improper use of it might have adverse affect of application performance.
This restriction allows you (force you) to put more focus into business logic than memory managemnt
JVM is the best person to decide when memory management is required and how to do it.
You can (should) trust JVM and let it handle things in better way than we can.
Still do you really want to force object destruction? If yes, WHY?
In order to ensure that programs run smoothly within the JVM, the JVM itself manages garbage collection.
Garbage collection has become quite sophisticated. When you ask the system for a GC run, which algorithm are you expecting? A "full GC"? There are multiple heaps, as well; which one is the garbage you are concerned about on? You don't know and this method doesn't indicate.
Suppose calling System.gc() always triggered a full GC. An errant program could easily grind JVM performance to a halt. Defensively, the JVM would want to limit the frequency at which it responded to such calls.
If you are running in a JVM on a non-embedded system (e.g. a server or a desktop computer), there should be no reason for you to concern yourself with any aspect of memory management other than to monitor it and code efficiently.
There are several metrics that are utilized to evaluate garbage collector performance , some of them are:
Throughput—the percentage of total time not spent in garbage collection, considered over long periods of time.
Garbage collection overhead—the inverse of throughput, that is, the percentage of total time spent in
garbage collection.
Pause time—the length of time during which application execution is stopped while garbage collection is occurring.
Frequency of collection—how often collection occurs, relative to application execution.
Footprint—a measure of size, such as heap size.
Promptness—the time between when an object becomes garbage and when the memory becomes
available.
Now If JVM listens to System.gc() like good pet and guarantees to perform action on each System.gc() call, Imagine what would be the performance of application if it is called many times within program.!!??
Throughput will decrease
Garbage Collection overhead will increase.
Application will pause many times as it is busy in recollecting the memory.
If Footprint is large , The garbage Collector would have to scan all memory area for recovering the memory , no matter if there are objects eligible for garbage collection or not.
So , after looking through these points I guess it provides the sufficient reason to JVM to not respond to System.gc on the application choice , but on its own algorithm. And Garbage Collection reclaims all unused object's memory for sure , but its invocation is entirely dependent on JVM own Algorithm rather than on the user's choice.
Source: Memory Management in the Java HotSpot™ Virtual Machine - Sun Microsystems
it cannot certainly reclaim all unused object's memory whenever it is invoked
This assumption of yours is false. In most cases the Garbage Collector could reclaim all unused objects at any point in time. However, if the standard Java library provided a method that would guarantee that, it would put a completely unreasonable burden on the GC subsystem to provide a service that is most of the time useless and could be even damaging.

Categories