I have read about making an object explicitly garbage collected, that in many ways. So i wanted to know some of the methods of making it explicitly garbage collected
There is no way for explicit garbage collection.
You can "politely ask" the virtual machine to do garbage collection by calling:
System.gc();
but it is not guaranteed it will.
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.
and "best effort" might be to postpone the garbage collection.
For how to make objects elligible for garbage collection read Effective Java, Chapter 2
You can explicitly make an object eligible for garbage collection by setting all references to it to null.
This won't call the garbage collector itself, but when the collection does start, it will collect this object.
You're best off letting the Java garbage collector doing it all automatically by itself. It has been optimized to the point where it'll be better and more efficient than anything you'd ever want to probably do.
System.gc is to tell the JVM to execute the garbage collector explicitly.
But as for as some methods which i know to make an object explicitly garbage collected are:
Assigning its reference to point to null
EX: Animal a = new Animal();
a = null
Assigning its reference to point to another object.
EX: Animal a1 = new Animal();
a1 = new Animal();
You shouldn't worry about forcing a GC unless you're writing, say, a tool like VisualVM yourself.
NetBeans, IntelliJ, VisualVM, and a great many others can all force a GC, not hint, but really force. Using JVMTI you can force a GC.
BUT once again you probably do NOT want to do that.
You force a GC (not hint) using JVMTI's ForceGarbageCollection.
That said, you probably really DO NOT want to do that (it really bares repeating).
Authoritative info on the subject if you really want to know (but you probably don't) how to force, for a fact, a GC:
http://java.sun.com/javase/6/docs/platform/jvmti/jvmti.html#ForceGarbageCollection
Related
I have some objects in my code which are not invoked in everyloop,But they are useful in future when some forced termination from loop,unpredictable error etc happens, So how to make sure that this objects are not ever collected by garbage collector.
For example : I have one class so I dont want GC to perform any Garbage collection on this class
If the objects are valuable and expensive to create, you should hang on to them in a field in your class. You could create a Map that would act sort of like a cache and grab them out of the Map when you're ready to use them again.
If they are useful in the future you have a reference to these objects somewhere. This is enough to ensure that they will never be garbage collected.
Keep a strong reference to the object, Doing this will always ensure that your object will not be GCed. I would also leave such things to the Garbage collector which I think is smarter than us(with all due respect) when it comes to memory management
You should have a look at the scope of your variables. as long as they are in scope they should not be garbage collected.
Garbage Collector Simply Avoids The Object Which Have Any Reference In The Code Further. So If You Want Any Object To Never Get Collected By G.C. Until The Execution Of Your Code. Just Have A Global Reference To That Object.
In Java, at some point in code I want to free memory taken by a huge HashMap<Integer, ArrayList<Integer>> object. Is it enough to point it to null like below:
Map<Integer, ArrayList<Integer>> complexObject = new HashMap<Integer, ArrayList<Integer>>(1000000);
...
complexObject = null;
?
You cannot explicitly de-allocate Java objects. But you can do the following:
Remove all references to the item you no longer need. You can do this by setting your only reference to an object to null.
Call System.gc() to "suggest" to the JVM to run the garbage collector, which deallocates no-longer used objects, although it's not guaranteed that calling this method will actually run the garbage collector.
Setting its reference to null will mark it available to the garbage collector next time it decides to run if there are indeed no more references to said object laying around anywhere. When the GC decides to run however, is not set in stone.
This is a big point where Java is different from C, but don't worry. 99.9% of the time you can trust the GC has your back.
There is no guarantee of freeing memory. GC will run and pickup nulls so that's all you can do yes.
I just read this article, there is something about freeing memory in it, too.
Check it out, nulling does not always help you.
Java programmers know that JVM runs a Garbage Collector, and System.gc() would just be a suggestion to JVM to run a Garbage Collector. It is not necessarily that if we use System.gc(), it would immediately run the GC.Please correct me if I misunderstand Java's Garbage Collector.
Is/are there any other way/s doing memory management other than relying on Java's Garbage Collector?If you intend to answer the question by some sort of programming practice that would help managing the memory, please do so.
The most important thing to remember about Java memory management is "nullify" your reference.
Only objects that are not referenced are to be garbage collected.
For example, objects in the following code is never get collected and your memory will be full just to do nothing.
List objs = new ArrayList();
for (int i = 0; i < Integer.MAX_VALUE; i++) objs.add(new Object());
But if you don't reference those object ... you can loop as much as you like without memory problem.
List objs = new ArrayList();
for (int i = 0; i < Integer.MAX_VALUE; i++) new Object();
So what ever you do, make sure you remove reference to object to no longer used (set reference to null or clear collection).
When the garbage collector will run is best left to JVM to decide. Well unless your program is about to start doing things that use a lot of memory and is speed critical so you may suggest JVM to run GC before going in as you may likely get the garbaged collected and extra memory to go on. Other wise, I personally see no reason to run System.gc().
Hope this helps.
Below is little summary I wrote back in the days (I stole it from some blog, but I can't remember where from - so no reference, sorry)
There is no manual way of doing garbage collection in Java.
Java Heap is divided into three generation for the sake of garbage collection. These are the young generation, tenured or old generation, and Perm area.
New objects are created in the young generation and subsequently moved to the old generation.
String pool is created in Perm area of Heap, Garbage collection can occur in perm space but depends on upon JVM to JVM.
Minor garbage collection is used to move an object from Eden space to Survivor 1 and Survivor 2 space, and Major collection is used to move an object from young to tenured generation.
Whenever Major garbage collection occurs application, threads stops during that period which will reduce application’s performance and throughput.
There are few performance improvements has been applied in garbage collection in Java 6 and we usually use JRE 1.6.20 for running our application.
JVM command line options -Xms and -Xmx is used to setup starting and max size for Java Heap. The ideal ratio of this parameter is either 1:1 or 1:1.5 based on my experience, for example, you can have either both –Xmx and –Xms as 1GB or –Xms 1.2 GB and 1.8 GB.
Command line options: -Xms:<min size> -Xmx:<max size>
Just to add to the discussion: Garbage Collection is not the only form of Memory Management in Java.
In the past, there have been efforts to avoid the GC in Java when implementing the memory management (see Real-time Specification for Java (RTSJ)). These efforts were mainly dedicated to real-time and embedded programming in Java for which GC was not suitable - due to performance overhead or GC-introduced latency.
The RTSJ characteristics
Immortal and Scoped Memory Management - see below for examples.
GC and Immortal/Scoped Memory can coexist withing one application
RTSJ requires a specially modified JVM.
RTSJ advantages:
low latency, no GC pauses
delivers predictable performance that is able to meet real-time system requirements
Why RTSJ failed/Did not make a big impact:
Scoped Memory concept is hard to program with, error-prone and difficult to learn.
Advance in Real-time GC algoritms reduced the GC pause-time in such way that Real-time GCs replaced the RTSJ in most of the real-time apps. However, Scoped Memories are still used in places where no latencies are tolerated.
Scoped Memory Code Example (take from An Example of Scoped Memory Usage):
import javax.realtime.*;
public class ScopedMemoryExample{
private LTMemory myMem;
public ScopedMemoryExample(int Size) {
// initialize memory
myMem = new LTMemory(1000, 5000);
}
public void periodicTask() {
while (true)) {
myMem.enter(new Runnable() {
public void run() {
// do some work in the SCOPED MEMORY
new Object();
...
// end of the enter() method, the scoped Memory is emptied.
}
});
}
}
}
Here, a ScopedMemory implementation called LTMemory is preallocated. Then a thread enters the scoped memory, allocates the temporary data that are needed only during the time of the computation. After the end of the computation, the thread leaves the scoped memory which immediately makes the whole content of the specific ScopedMemory to be emptied. No latency introduced, done in constant time e.g. predictable time, no GC is triggered.
From my experience, in java you should rely on the memory management that is provided by JVM itself.
The point I'd focus on in this topic is to configure it in a way acceptable for your use case. Maybe checking/understanding JVM tuning options would be useful: http://docs.oracle.com/cd/E15523_01/web.1111/e13814/jvm_tuning.htm
You cannot avoid garbage collection if you use Java. Maybe there are some obscure JVM implementations that do, but I don't know of any.
A properly tuned JVM shouldn't require any System.gc() hints to operate smoothly. The exact tuning you would need depends heavily on what your application does, but in my experience, I always turn on the concurrent-mark-and-sweep option with the following flag: -XX:+UseConcMarkSweepGC. This flag allows the JVM to take advantage of the extra cores in your CPU to clean up dead memory on a background thread. It helps to drastically reduce the amount of time your program is forcefully paused when doing garbage collections.
Well, the GC is always there -- you can't create objects that are outside its grasp (unless you use native calls or allocate a direct byte buffer, but in the latter case you don't really have an object, just a bunch of bytes). That said, it's definitely possible to circumvent the GC by reusing objects. For instance, if you need a bunch of ArrayList objects, you could just create each one as you need it and let the GC handle memory management; or you could call list.clear() on each one after you finish with it, and put it onto some queue where somebody else can use it.
Standard best practices are to not do that sort of reuse unless you have good reason to (ie, you've profiled and seen that the allocations + GC are a problem, and that reusing objects fixes that problem). It leads to more complicated code, and if you get it wrong it can actually make the GC's job harder (because of how the GC tracks objects).
Basically the idea in Java is that you should not deal with memory except using "new" to allocate new objects and ensure that there is no references left to objects when you are done with them.
All the rest is deliberately left to the Java Runtime and is - also deliberately - defined as vaguely as possible to allow the JVM designers the most freedom in doing so efficiently.
To use an analogy: Your operating system manages named areas of harddisk space (called "files") for you. Including deleting and reusing areas you do not want to use any more. You do not circumvent that mechanism but leave it to the operating system
You should focus on writing clear, simple code and ensure that your objects are properly done with. This will give the JVM the best possible working conditions.
You are correct in saying that System.gc() is a request to the compiler and not a command. But using below program you can make sure it happens.
import java.lang.ref.WeakReference;
public class GCRun {
public static void main(String[] args) {
String str = new String("TEMP");
WeakReference<String> wr = new WeakReference<String>(str);
str = null;
String temp = wr.get();
System.out.println("temp -- " + temp);
while(wr.get() != null) {
System.gc();
}
}
}
I would suggest to take a look at the following tutorials and its contents
This is a four part tutorial series to know about the basics of garbage collection in Java:
Java Garbage Collection Introduction
How Java Garbage Collection Works?
Types of Java Garbage Collectors
Monitoring and Analyzing Java Garbage Collection
I found This tutorial very helpful.
"Nullify"ing the reference when not required is the best way to make an object eligible for Garbage collection.
There are 4 ways in which an object can be Garbage collected.
Point the reference to null, once it is no longer required.
String s = new String("Java");
Once this String is not required, you can point it to null.
s = null;
Hence, s will be eligible for Garbage collection.
Point one object to another, so that both reference points to same object and one of the object is eligible for GC.
String s1 = new String("Java");
String s2 = new String("C++");
In future if s2 also needs to pointed to s1 then;
s1 = s2;
Then the object having "Java" will be eligible for GC.
All the objects created within a method are eligible for GC once the method is completed. Hence, once the method is destroyed from the stack of the thread then the corresponding objects in that method will be destroyed.
Island of Isolation is another concept where the objects with internal links and no extrinsic link to reference is eligible for Garbage collection.
"Island of isolation" of Garbage Collection
Examples:
Below is a method of Camera class in android. See how the developer has pointed mCameraSource to null once it is not required. This is expert level code.
public void release() {
if (mCameraSource != null) {
mCameraSource.release();
mCameraSource = null;
}
}
How Garbage Collector works?
Garbage collection is performed by the daemon thread called Garbage Collector. When there is sufficient memory available that time this demon thread has low priority and it runs in background. But when JVM finds that the heap is full and JVM wants to reclaim some memory then it increases the priority of Garbage collector thread and calls Runtime.getRuntime.gc() method which searches for all the objects which are not having reference or null reference and destroys those objects.
I encountered this question in an interview with following options:
How to destroy an object in java?
a. System.gc();
b. Runtime.getRuntime.gc();
c. object.delete();
d. object.finalize();
e. Java performs gc by itself, no need to do it manually.
The answer should be e?
what if e was not there? then ?
clearly c is not the answer. a and b will do gc for the whole application(question requires for one object).
I think it is d because finalize() is called just prior to gc(but is it necessary that after finalize gc is invoked ?) or I am wrong ? e must be there to answer this question ?
Answer E is correct answer. If E is not there, you will soon run out of memory (or) No correct answer.
Object should be unreachable to be eligible for GC. JVM will do multiple scans and moving objects from one generation to another generation to determine the eligibility of GC and frees the memory when the objects are not reachable.
To clarify why the other answers can not work:
System.gc() (along with Runtime.getRuntime().gc(), which does the exact same thing) hints that you want stuff destroyed. Vaguely. The JVM is free to ignore requests to run a GC cycle, if it doesn't see the need for one. Plus, unless you've nulled out all reachable references to the object, GC won't touch it anyway. So A and B are both disqualified.
Runtime.getRuntime.gc() is bad grammar. getRuntime is a function, not a variable; you need parentheses after it to call it. So B is double-disqualified.
Object has no delete method. So C is disqualified.
While Object does have a finalize method, it doesn't destroy anything. Only the garbage collector can actually delete an object. (And in many cases, they technically don't even bother to do that; they just don't copy it when they do the others, so it gets left behind.) All finalize does is give an object a chance to clean up before the JVM discards it. What's more, you should never ever be calling finalize directly. (As finalize is protected, the JVM won't let you call it on an arbitrary object anyway.) So D is disqualified.
Besides all that, object.doAnythingAtAllEvenCommitSuicide() requires that running code have a reference to object. That alone makes it "alive" and thus ineligible for garbage collection. So C and D are double-disqualified.
Short Answer - E
Answer isE given that the rest are plainly wrong, but ..
Long Answer - It isn't that simple; it depends ...
Simple fact is, the garbage collector may never decide to garbage collection every single object that is a viable candidate for collection, not unless memory pressure is extremely high. And then there is the fact that Java is just as susceptible to memory leaks as any other language, they are just harder to cause, and thus harder to find when you do cause them!
The following article has many good details on how memory management works and doesn't work and what gets take up by what. How generational Garbage Collectors work and Thanks for the Memory ( Understanding How the JVM uses Native Memory on Windows and Linux )
If you read the links, I think you will get the idea that memory management in Java isn't as simple as a multiple choice question.
Set to null. Then there are no references anymore and the object will become eligible for Garbage Collection. GC will automatically remove the object from the heap.
Here is the code:
public static void main(String argso[]) {
int big_array[] = new int[100000];
// Do some computations with big_array and get a result.
int result = compute(big_array);
// We no longer need big_array. It will get garbage collected when there
// are no more references to it. Since big_array is a local variable,
// it refers to the array until this method returns. But this method
// doesn't return. So we've got to explicitly get rid of the reference
// ourselves, so the garbage collector knows it can reclaim the array.
big_array = null;
// Loop forever, handling the user's input
for(;;) handle_input(result);
}
In java there is no explicit way doing garbage collection. The JVM itself runs some threads in the background checking for the objects that are not having any references which means all the ways through which we access the object are lost. On the other hand an object is also eligible for garbage collection if it runs out of scope that is the program in which we created the object is terminated or ended.
Coming to your question the method finalize is same as the destructor in C++. The finalize method is actually called just before the moment of clearing the object memory by the JVM. It is up to you to define the finalize method or not in your program. However if the garbage collection of the object is done after the program is terminated then the JVM will not invoke the finalize method which you defined in your program.
You might ask what is the use of finalize method?
For instance let us consider that you created an object which requires some
stream to external file and you explicitly defined a finalize method to this object which checks wether the stream opened to the file or not and if not it closes the stream. Suppose, after writing several lines of code you lost the reference to the object. Then it is eligible for garbage collection. When the JVM is about to free the space of your object the JVM just checks have you defined the finalize method or not and invokes the method so there is no risk of the opened stream. finalize method make the program risk free and more robust.
Hopefully a simple question. Take for instance a Circularly-linked list:
class ListContainer
{
private listContainer next;
<..>
public void setNext(listContainer next)
{
this.next = next;
}
}
class List
{
private listContainer entry;
<..>
}
Now since it's a circularly-linked list, when a single elemnt is added, it has a reference to itself in it's next variable. When deleting the only element in the list, entry is set to null. Is there a need to set ListContainer.next to null as well for Garbage Collector to free it's memory or does it handle such self-references automagically?
Garbage collectors which rely solely on reference counting are generally vulnerable to failing to collection self-referential structures such as this. These GCs rely on a count of the number of references to the object in order to calculate whether a given object is reachable.
Non-reference counting approaches apply a more comprehensive reachability test to determine whether an object is eligible to be collected. These systems define an object (or set of objects) which are always assumed to be reachable. Any object for which references are available from this object graph is considered ineligible for collection. Any object not directly accessible from this object is not. Thus, cycles do not end up affecting reachability, and can be collected.
See also, the Wikipedia page on tracing garbage collectors.
Circular references is a (solvable) problem if you rely on counting the references in order to decide whether an object is dead. No java implementation uses reference counting, AFAIK. Newer Sun JREs uses a mix of several types of GC, all mark-and-sweep or copying I think.
You can read more about garbage collection in general at Wikipedia, and some articles about java GC here and here, for example.
The actual answer to this is implementation dependent. The Sun JVM keeps track of some set of root objects (threads and the like), and when it needs to do a garbage collection, traces out which objects are reachable from those and saves them, discarding the rest. It's actually more complicated than that to allow for some optimizations, but that is the basic principle. This version does not care about circular references: as long as no live object holds a reference to a dead one, it can be GCed.
Other JVMs can use a method known as reference counting. When a reference is created to the object, some counter is incremented, and when the reference goes out of scope, the counter is decremented. If the counter reaches zero, the object is finalized and garbage collected. This version, however, does allow for the possibility of circular references that would never be garbage collected. As a safeguard, many such JVMs include a backup method to determine which objects actually are dead which it runs periodically to resolve self-references and defrag the heap.
As a non-answer aside (the existing answers more than suffice), you might want to check out a whitepaper on the JVM garbage collection system if you are at all interested in GC. (Any, just google JVM Garbage Collection)
I was amazed at some of the techniques used, and when reading through some of the concepts like "Eden" I really realized for the first time that Java and the JVM actually could beat C/C++ in speed. (Whenever C/C++ frees an object/block of memory, code is involved... When Java frees an object, it actually doesn't do anything at all; since in good OO code, most objects are created and freed almost immediately, this is amazingly efficient.)
Modern GC's tend to be very efficient, managing older objects much differently than new objects, being able to control GCs to be short and half-assed or long and thorough, and a lot of GC options can be managed by command line switches so it's actually useful to know what all the terms actually refer to.
Note: I just realized this was misleading. C++'s STACK allocation is very fast--my point was about allocating objects that are able to exist after the current routine has finished (which I believe SHOULD be all objects--it's something you shouldn't have to think about if you are going to think in OO, but in C++ speed may make this impractical).
If you are only allocating C++ classes on the stack, it's allocation will be at least as fast as Java's.
Java collects any objects that are not reachable. If nothing else has a reference to the entry, then it will be collected, even though it has a reference to itself.
yes Java Garbage collector handle self-reference!
How?
There are special objects called called garbage-collection roots (GC roots). These are always reachable and so is any object that has them at its own root.
A simple Java application has the following GC roots:
Local variables in the main method
The main thread
Static variables of the main class
To determine which objects are no longer in use, the JVM intermittently runs what is very aptly called a mark-and-sweep algorithm. It works as follows
The algorithm traverses all object references, starting with the GC
roots, and marks every object found as alive.
All of the heap memory that is not occupied by marked objects is
reclaimed. It is simply marked as free, essentially swept free of
unused objects.
So if any object is not reachable from the GC roots(even if it is self-referenced or cyclic-referenced) it will be subjected to garbage collection.
Simply, Yes. :)
Check out http://www.ibm.com/developerworks/java/library/j-jtp10283/
All JDKs (from Sun) have a concept of "reach-ability". If the GC cannot "reach" an object, it goes away.
This isn't any "new" info (your first to respondents are great) but the link is useful, and brevity is something sweet. :)