JVM has Garbage collectors that will execute when ever heap is short of memory. You cannot directly influence the JVM to run the garbage collectors. And you would have to carefully develop applications considering the platform.
On a lower memory devices you will not have access to all the APIs (that which are in JavaSE) and also one would have to be careful enough while developing applications for platforms with lower resources.

Keep the following points in your mind when coding an application for memory management.

Always close the resources when you think they are no longer needed
Avoid using String use StringBuffer Be careful when using Loops in your code
Clean up heavy objects by setting their values to NULL when you think they are no longer needed
If Appropriate force for garbage collection using RunTime.gc()

Ifteqar Ahmed wrote:Always close the resources when you think they are no longer needed

That is generally a good practice.

Avoid using String use StringBuffer

While this cuts down on intermediate object creation, it doesn't help with memory issues, all the objects are automatically reclaimed by the GC. What's more, object creation has long ceased to be a drag on the JVM.

Be careful when using Loops in your code
Clean up heavy objects by setting their values to NULL when you think they are no longer needed
If Appropriate force for garbage collection using RunTime.gc()

These are of no value with respect to memory management, or downright discouraged. Don't follow these.

Make sure you don't hold references to objects longer than you need to. A big problem is putting objects into a collection and keeping that collection in scope when you no longer need it. Once it's out of scope, Java's garbage collection will take over and there's no need to set references to null right before they go out of scope (e.g. before a method return), which I still see people doing. However, it's up to you to intelligently control the scope of your objects.

Look for ways to stream data. Take XML parsing for example. There are parsers that force you to read the whole structure into memory and others that let you read it in bit by bit. If memory is a big issue, use the bit by bit parsers. The same goes for any kind of data processing you're doing. If you don't need the whole data structure in one place to do your processing, just read a chunk of it, do your processing, and pass that chunk on to where ever it's going before reading the next chunk.

With regard to Strings, I'm a bit confused. I vaguely remember the JVM doesn't garbage collect unused Strings the same way it does with other Objects. Maybe that's only true of String literals? In any case I do recommend using StringBuilder (not StringBuffer unless you need thread synchronization) to build up Strings from parts. Don't go nuts with it though. You don't need it to concatenate two or three strings, but when you're doing something more complicated, it's definitely a good tool.

They'll all get freed as long as there are no other references to them. It also doesn't matter if, for instance, two objects refer to each other. As long as nothing that's in scope is referring to either of them the garbage collector will realise they're isolated and can clean them up.