Calling System.gc () on mobile devices
The reason for all the nulling of attributes and calls to System.gc () is some part of the fight against device fragmentation. It's easy to say that you should never ignore value on your own, that you should just let it go out of scope, and this is actually the way to go for PC development. However, the mobile space is a completely different animal, and it would be naive to say that you can manage memory in the same way on a limited mobile device as you can on a PC that has RAM gigs and gigs at its disposal.
Even now, high-end smartphones have about 32-64MB of heap available for the J2ME app. Many devices are still around 1-4 MB and often even smaller heap sizes must be used to meet carrier specifications. Razr only has 800k heaps and still needs support from most carriers due to the fact that many of their subscribers are still using the device.
Memory fragmentation occurs because although a block of memory is no longer in use, that it was invalidated, it is not yet available until garbage collected. Most mobile VMs only GC when memory is needed. So when it finally starts the GC, the heap can be fragmented into tiny blocks of memory. When a larger block of memory needs to be allocated, it cannot allocate a smaller block. If you have enough of these smaller blocks polluting the heap without supplying a block big enough for a larger object, you will end up with an OutOfMemory exception, although it might seem like you have a ton of memory.
For example, imagine you are creating a local variable Object that requires 50 bytes. Then you allocate a member variable that will persist for the lifetime of the application, which requires 200 bytes of heap. If you do this process over and over, you may end up in a situation where you have thousands of blocks of memory that are only 50 bytes long. Since a persistent object takes 200 bytes, you end up screwing up and getting an OutOfMemory exception.
Now if you created the same String object that it used, then it declared it itself and called System.gc () (also you can call Thread.yield () to give the GC the ability to run) then you have those 50 bytes to create a new persistent object, avoid fragmentation and avoid OutOfMemory exceptions.
This is a very simple example, but if you have a lot of large images, for example in a game application, you quickly find yourself in this situation in the mobile space.
One final note, with BlackBerry devices, you should avoid calling the garbage collector yourself, as it is much more complex (it will defragment the heap for you). Being more complex makes it much slower (we're talking a few seconds per turn) than the usual down and dirty GCs on most devices.
a source to share
On a good modern VM, this doesn't make sense for System.gc () at all. As a general rule, it never makes sense to set attributes to null unless it can be made unavailable.
On less complex virtual machines that you might get on mobile devices, it would be wise to null out the link if it is no longer partially used through a method, but is still in scope. (On modern desktop VMs like Hotspot, this is generally no longer required - the VM has its code in front of it and can usually decide if you will still use a local link, regardless of scope.)
Now, going back to System.gc (), it is true that mobile virtual machines have historically been simpler than the rather complex "full-fledged" virtual machines that we are used to like Hotspot. But:
- In recent years, mobile virtual machines have emerged a lot - facility throughput, like other aspects of performance, has definitely improved on many devices;
- System.gc () has no consistent, well-defined behavior anyway . On some devices, it cannot do anything; on others, like desktop virtual machines, this can cause the type of garbage collection to actually hurt performance compared to the normal "incremental" garbage collection that the virtual machine automatically performs while the application is running.
So I would be very careful about using System.gc ().
a source to share
It's a big urban legend in the Java world that calls System.gc () actually, reliably does something for you. It won't.
This is just an assumption that the JVM is trying to do something. The Javadoc for a method is purposefully ambiguous in this regard.
Another big bugbear is link nulling. When the link goes out of scope, it is already disabled by the virtual machine and this makes it redundant and misleading. If there are any more links, they will still be available and your assignment will do nothing (unless you go and visit any link available), but then, what's the point? Which is what VM already does).
So, to answer your questions:
- It rarely makes sense to set attributes to zero. Build your software properly so that links go out of scope when you no longer use them.
- Calling System.gc () rarely makes sense. Let the JVM do the work for you - that's why we use a virtual machine instead of managing our own memory.
- Yes, let the VM manage your memory, it will be GC when needed. However, if you have poorly designed software, it can beat GC in a virtual machine. In that case, watch out for memory leaks and software refactorings (easier said than done, though).
a source to share
All the answers to this question so far are completely correct, basically that you cannot rely on System.gc () to do anything. This is a platform specific and MIDP2 does not provide any real specifications for how it should behave.
However, it is usually implemented appropriately, although you cannot say that "this object is now deleted", etc., I find it acceptable and appropriate to use a call under certain circumstances. For example, if your application needs to do a big delete, then an allocation (like resetting or changing states), making a call right after it tells the VM is the right time to collect.
James
By setting the attributes to null (thus destroying some of the object references), the GC must claim those objects. Maybe they are no longer needed and the developers wanted to free up memory?
I've heard that not every J2ME target has a GC. But if so, it makes sense to call System.gc (), so the garbage collector won't kick when you're doing something in real time.
a source to share