How to free object in android? [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java garbage collection
I know that we have to free object in C, C++ after processing finish to get back the memory. However, I don't know how to free object in java and android. Is that enough for just assign null to the object?

In Java it is un-necessary to free objects.
Java has a built in Garbage Collector which runs when ever it needs to and clear out all resources that are no longer in use in order to free memory. A java developer may make a call to the java runtime to run the Garbage Collecter using System.gc(); however this is just a suggestion to the runtime and may not always result in it being run.
In cases where you are using readers and images, be sure to call .recycle() and .close() where applicable.

A simple java object especially (E.g. model objects) can be freed by garbage collector IF other objects has no reference to it.
If I were you, don't trust too much that garbage collector because there are some objects that you must free, one of them is the Bitmap objects
Bitmaps eat more RAM in your android app.
Bitmap b = createLargeBitmap();
Bitmap b2 = b;
If you remove all references to that object and let garbage collector kill it
b = null;
b2 = null;
you might get a memory leak or OutOfMemory error.
So you need to call recycle() to fully freed the bitmap.
b.recycle();
b = null;
b2 = null;
// Sorry for my wrong grammar :)

In most cases, setting a var to null is enough. A better answer to answer your questions is how to leak the memory which details explained in this post .

Memory deallocation is automatically done by Java garbage collector . You can't force garbage collector to free memory through your code.
Calling System.gc() doesnot guarantee garbage collector to RUN and FREE memory , final decision is taken by Java runtime.

Android (which uses Java language) is a garbage-collected environment, meaning the virtual machine will automatically remove objects which no longer have any references.
Hence the question you should be asking is: how do you ensure your program does not use too much memory. This is normally achieved by ensuring you don't put too many objects in your in-memory data structure, persist your information into file system etc.

Related

Is there any way that I can free up memory in the java code that is generated to bind C code via JNI/JNA?

I am using a java library that use JNA to bind to the original C library (That library is called Leptonica). I encountered a situation where free(data) has to be called in the C code to free up the memory. But, is there any function in java that I can free up the memory?
In the C code
void ImageData::SetPixInternal(Pix* pix, GenericVector<char>* image_data) {
l_uint8* data;
size_t size;
pixWriteMem(&data, &size, pix, IFF_PNG);
pixDestroy(&pix);
image_data->init_to_size(size, 0);
memcpy(&(*image_data)[0], data, size);
free(data);
}
The function pixWriteMem() will create and allocate memory to the "data", which you need to do free(data) to free up the memory later.
In Java code, I can only access pixWriteMem(), not the SetPixInternal(), so I have no way to free up the "data", which create a memory leak.
The other comments and answers here all seem to be suggesting that you just rely on the garbage collector or tell the garbage collector to run. That is not the correct answer for memory allocated in C and being used in Java via JNI.
It looks like that execution() does free the memory. The last line you show us is free(data). Still, to answer your the question as you asked it, the answer is "not directly." If you have the ability to add to the C code, you could create another C function which frees the data and then call that using JNI. Perhaps there is more that we are not seeing which relates better to your concern about the memory leak?
Also, be careful about freeing memory allocated by a library you are using. You should make sure that the library doesn't still need it and is leaking it before you go trying to free it.
And now back to memory management in general...
Java is indeed a garbage-collected language. This means that you do not specifically delete objects. Instead, you make sure there are no references to it, then the garbage collector takes care of the memory management. This does not mean that Java is free from memory leaks, as there are ways to accidentally keep a reference hanging around such that the object never gets garbage collected. If you have a situation like this, you might want to read up on the different kinds of references in Java (strong/weak/etc.).
Again, this is not the problem here. This is a C/Java hybrid, and the code in question is in C being called by Java. In C, you allocate the memory you want to use and then you need to free the memory yourself when you are done with it. Even if the C code is being run by Java via the JNI, you are still responsible for your own memory. You cannot just malloc() a bunch of memory and expect the Java garbage collector to know when to clean it up. Hence the OP's question.
If you need to add the functionality yourself to do a free, even without the source code for the C part, you might still be able to write your own C interface for freeing the memory if you have access to the pointer to the memory in question. You could write basically a tiny library that just frees the memory for you, make the JNI interface for it, and pass the pointer to that. If you go this route then, depending on your OS, you might need to guarantee that your tiny free library's native code is running in the same process as the rest of the native code, or if not the same process then at least that the process you run it from has write access to the memory owned by the other code's process; this memory/process issue is probably not an issue in your case, but I'm throwing it out there for completeness.
In Java code, I can only access createData(), not the excution(), so I have no way to free up the "data", which create a memory leak.
Then it sucks to be you.
Seriously, if you want to free memory allocated by a native method and not freed before that method returns, then you need to maintain a handle of some kind on that memory and later pass it to another native method that will free the memory. If you do not presently have such a native method available, then you'll need to create one.
The other question is how to ensure that the needed native method is invoked. Relying on users to invoke it, directly or indirectly, leaves you open to memory leaks should users fail to do so. There are two main ways to solve that problem:
Give your class a finalizer that ensures the memory is freed. This is the core use case for finalizers, but even so, there are good reasons to prefer to avoid writing them. The other alternative is to
Create a reference object (SoftReference, WeakReference, or PhantomReference), associate the reference with a mechanism for freeing the native-allocated memory belonging to the referenced Java object (but not via that object), and register that object with a reference queue. The reference will be enqueued when the object is GC'd, at which point you know to free the native-allocated memory.
That does not necessarily mean that you should prevent users from explicitly freeing the memory, for with enough bookkeeping you can track whether anything still needs to be freed at any given time. Allowing users to release resources explicitly may help keep your overall resource usage lower. But if you want to avoid memory leaks then you need to have a fallback.
No there is no function like C's free() in Java. But you can suggest garbage collector to run by calling System.gc()

Ways to check at runtime whether an object has been garbage collected in Java? [duplicate]

is there a way to check if an object can be fetched by the garbage collector?
Somewhere in my code I've got a reference to an object:
MyObject mo = myObject;
Then, via Eclipse Debugger, I get the objects memory location. Afterwards, I set the reference null:
mo = null;
Is there any way to check if the previously referenced object is now suitable for garbage collection or if there's somewhere another reference to it?
Thanks a lot,
Stefan
You cannot do this at runtime with an arbitrary object, and in fact it's not fully possible to do this deterministically. However, there are two options that may be suitable depending on your needs:
Take a heap dump after you set the reference to null, and then load it up in a heap analyzer tool such as jhat or a profiler that supports this. These tools should let you traverse the path from the GC roots and thus check if your object is still reachable or not.
Wrap the object in a PhantomReference with a given ReferenceQueue. When the reference is enqueued, you know that the object has been garbage collected. (Unfortunately, if the reference is unqueued it could be because the object is still reachable, or it could be because the GC just hasn't inspected the object yet. As with all GC-related questions, garbage collection is not a deterministic process!)
On the whole though, I agree that the best option is to be aware of memory leak issues and design your application to avoid them. If you do have a memory leak it should be obvious enough, and you can then focus your energies on finding the problem (again by dumping and analysing the heap for objects that are incorrectly reachable).
The steps above are relatively time-consuming, and shouldn't be something that you do after every change just to reassure yourself, but rather are tools you'd use to investigate a specific problem.
No. The only thing to do is to be careful and keep in mind that memory leaks can exist in Java when writing your application.
The only you can do, is to use tools to try to find where memory leaks come from when you noticed such a problem. I would strongly recommend Memory Analyzer for this purpose.

Java Memory management and when to destroy object [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have written a small Java program where I create 10 String Objects.
Can someone explain or answer the following questions.
What are the best practices to create a Object. ie; When I create a Object should I also make sure I delete the object once its used. If, How do I delete it?
If I don't delete the object, is that the object will be lying until the program ends?
Is there a way to check the number of active objects when a program is running?
public class Test{
static public void main(String[] args){
for (Integer i = 0; i < 10; i ++){
String s1 = new String("Creating new String");
}
System.out.println("Program COmpleted");
}
}
When I create a Object should I also make sure I delete the object once its used.
No. You can not explicitly delete an Object in Java. For certain memory-intensive use cases, it might make sense to explicitly nullify references to your objects, to help the garbage collector with the cleanup process, but the object itself is not deleted until it is collected by the garbage collector.
If I don't delete the object, is that the object will be lying until the program ends?
No. The garbage collector will take care of deleting it, once there are no references to it anymore. The point in time when this happens is up to the garbage collector - this might also be at the end of your application.
Is there a way to check the number of active objects when a program is running?
Yes, you can use a profiler such as YourKit.
See also
When does Java's garbage collection free a memory allocation?
Garbage Collection in the Java HotSpot Virtual Machine
Java Garbage Collection Basics
What are the best practices to create a Object. ie; When I create a Object should I also make sure I delete the object once its used. If, How do I delete it?
The best practices to create a Object is just when you want to use it.
Also you need to learn about variable scoping.
If I don't delete the object, is that the object will be lying until the program ends?
No, GC will kill un referenced objects
Is there a way to check the number of active objects when a program is running?
You can use any Java profiling tool such as vesualVM
Java is a Garbage Collected language, and therefore, most memory management and cleanup is done for you. This contrary to languages like C++ where one must manually free unused memory and generally be more cautious of possible memory leaks.
To address your specific questions:
Sometimes, it is considered good practice to "null out" unused object references. This is usually only true in specific instances, for example see: Does setting Java objects to null do anything anymore?.
No, not necessarily. If there is nothing pointing to the Object in memory, then the Garbage Collector should free up the unused memory.
You could use a debugger to keep track of the number of objects that are created as you step through your code line by line (I am not sure if this is robust enough a solution for your purposes).
Java has garbage collector. Garbage collector destroys objects when it's no longer used.
you can find gc basics here](http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html)
If you want to profile application use jvisualvm , which is packaged with JDK. If you want to count objects programmatically , use JMX API's (read oracle documentation about JMX)
The JVM automatically recycles objects that are no longer in use (this is called "garbage collection"). This happens when it feels like it, and when running out of previously unallocated memory, and returns the memory used by the unused objects to the unallocated memory pool.
All you have to do is to ensure that there is no variable through which you can use the objects any more - typically by assigning another value - and the rest happens automatically.
The simplest way to see how many objects are used by your program, is to use a profiler. You can use visualvm in the JDK or the one in Netbeans for free.

Java - Garbage collection

I found very less understanding in web about java gc. I request you to answer or correct my questions possibly by providing some reliable sources. I hope this post will be helpful to many people like me.
Q1) Please correct or improve my understanding about garbage collection:
gc will automatically be called by jvm during the execution of an application. Calling gc explicitly may only make the gc happen little early than it may happen without explicit call. JVM may call gc at irregular intervals, probably frequently.
gc may collect an object when (i) It's not being referenced by. and (ii) It's not referencing to.
but before destroying an object it will call finalize method of that object class where it can execute some code, normally cleanup operations wrt that object. Finalize method will be called only once per one object. If object is saved by finalize method at the first time, next time it can't escape from death.
If there are memory blocks allocated but not reclaimed due to exceptions/thread abortions they are called as memory leaks which may result in scarcity of memory in the system. OS may tackle with it but not in expected response time of running applications which need memory immediately on demand in which case applications may halt/hang with insufficient memory resource error dumps.
Q2) Garbage collection will only be for heap? ( That means, only to collect unreferenced objects? ) If so, what about static variables/constants/objects which are stored in class-method area?
Q3) How can we make a java object imperishable? Meaning... No matter what happens in the application, the object should not be reclaimed by gc through out the application life. Is it possible?
Q4) I am guessing there will be some occasions in program where gc may go wrong...meaning reclaim an object which shouldn't reclaim because it may gonna be used but gc didn't see the future use. Do such mistakes possible about what programmer should suspect or take care of this auto gc provided by java?
There are many wrong facts in your understanding.
Exceptions and thread abortions don't cause memory leaks. Memory leaks only happen when you keep references to objects for too long. A memory leak is thus caused by a bug in your code (or in a library that you're using), but not by the JVM.
A GC collects objects when the object is not reachable from any chain of references from a root object (variable on a thread stack or static variable). An object which still has references to other objects is not a problem at all. An object which is still referenced by other objects, but not reachable anymore is eligible to GC as well. That's what allows building complex graphs of objects with cyclic references without any problem.
Calling gc explicitly may cause GC to execute immediately, later, or not have any effect.
If the GC was buggy, it would be useless. It's not buggy. If it reclaims an object, then this object is not used anymore by the application.
To make an object not perishable, just make sure it's always reachable through a chain of references from a root. It could b referenced from a static variable, or by a local variable from a thread that never ends.
Q1 and Q2 I will try explaining how the variables get stored in JAVA, thus u can see how GC works.
If you declare
Object a ;
you have created a pointer to an object. It gets stored in the STACK but not in the HEAP.
If you later say
a = new Object();
The object gets placed into the HEAP. The pointer in the stack points to the place in the heap where your object is.
Further more, if you later write
a = null;
you have set the pointer in the STACK to nowhere. GC will destroy the item in the HEAP. Please note that the pointer is still in the STACK. Now if that all was a local variable ( inside function ) and the function exits at some time, the pointer in the STACK will be removed too, if it points at something in the heap, it gets removed too.
However if the variable belongs to an object that is let's say instance variable, the pointer will stay until the object itself exists - the object has memory allocated in the HEAP.
I hope you see what's going on here. It's a bit like chain reaction.
Q3 - You can make an object last until the program exits by making it STATIC.
About Q4 I am not quite sure.
On the topic of 4) the only time the GC can reclaim object you don't expect is when you play with References such as WeakReference and SoftReference. These wrapper allow the GC to clean up objects either on a collection, or when memory is low respectively. While this sounds like a great idea for caching it often doesn't behave quite the way you would expect and they are not as useful as they first appear.
Q1) Please correct or improve my understanding about garbage collection
(Most of your assumptions are correct)
A big problem in programming was memory management . At the begining the developers were responsible for its allocation
and release manually, which led to many bugs and memory leaks. Today , in
all modern platforms , including Java , the memory management is done by GC algorithms.
The Garbage Collector ( GC ) is a major component of the JVM and responsible
by releasing the memory that is no longer being used. When the
application releases all references to an object, it can be collected by the GC at any time, but the time is not determined. It depends entirely on the algorithm the garbage collector . In general , the GC will not make collections for each object. It will wait to release
blocks of objects, for optimization.
JVM may call gc at irregular intervals, probably frequently. (realy depends on the algorithm)
Q2) Garbage collection will only be for heap?
NO. The PermGen is out of the HEAP. Is where Class objects, Method, and the pool of strigs are allocated.
This space is also collected by the GC (when the FullGC is executed).
Q3) How can we make a java object imperishable?
If you have an objected that is never dereferenced, then it will always exist. (For example, in a web app, you add an object
in the applicationContext and you never take it from there. It will exist for the entire application, until it is shutdown).
Q4) Do such mistakes possible about what programmer should suspect or take care of this auto gc provided by java?
You should be aware of which GC algorithm your JVM is using, and choose one that best suit your needs.
(you can choose UseParallelGC / UseSerialGC / UseParallelOldGC / UseConcMarkSweepGC)
See here :
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html
Your understanding seem to be right except that OS doesn't do anything to reclaim the memory. When jvm starts you provide with the max heap that program can use and once that is completely used you will get an Out of Memory Error if there is a leak in the system. I also don't think that if you save your object in finalize it will cleaned up next time for sure. I think if you make finalize to reference your object back then it might never be cleaned up, i am not sure though.
The class and other static information goes to perm gen space. Once the program is restarted this area gets cleared up, but its possible to keep an handle of these information leaking which might result into Out of memory in perm gen space.
Make your object global and it will stay forever
GC has a small pause time where it rescues the objects which have been reference back. So NO you don't have to worry about GC claiming objects that are not supposed to.

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.

Categories