• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Getting System.gc() to run....

 
James Hodgkiss
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,
I can't be the only one that's had this problem, but there seems to be nothing in the forum already..... Please help!
I have a midlet which first displays a form, then (after the user presses 'Proceed') a canvas.
When the canvas is displayed, the user can press 'Back' to go back to the form, then if he presses 'Proceed' again (to create and display a canvas again), I get an 'unable to run application' error, and the midlet crashes.
The status window confirms that the amount of free heap memory is quite low after the user presses back - too low to create another canvas.
So I introduced a System.gc() line into my code (implemented in commandAction(), once the user presses 'Back') - but, according to the status window, it doesn't release any heap memory.
The only way I can get System.gc() to work effectively is to create another command:
Command commandRunGC = new Command("Run GC", Command.whatever, etc....);
with the user pressing this 'Run GC' button - and this works fine: it releases enough memory each time for me to go 'Back' and 'Proceed' as much as I want.
Problem is, of course, it's no good for the user having to press 'Run GC' every time before the they press 'Proceed'!
I've also tried running System.gc() just before the canvas is created, but no joy.
And I've tried running System.gc() in a new thread, but it's still ineffective.
I've also tried Runtime.getRuntime().gc(), but no success with that either.
Does anyone know how I can get the gc to run?!
Cheers,
James
PS - Can anyone explain the strange behaviour - why the gc will only run when I create a Command for it, and why the JVM doesn't run it automatically anyway - i.e., jusr before it attempts to create the canvas.
 
Michael Yuan
author
Ranch Hand
Posts: 1427
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In Java (also true in J2SE), when you call gc(), you *suggest* the system to run GC. But there is no promise *when* the system might run it. Sort of like when you call setCurrent() and repaint() in a MIDlet, there is no telling *when* they might take effect. But the system should definitely run the GC if the memory is that low (not enough for another Form??).
Which emulator are you developing on?
 
James Hodgkiss
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hiya Michael,
It happens on the Nokia 7210 and 3510i emulators and also on the 7210 handset. It looks like a problem with the JVM. It obviously isn't making its decisions very well as to when to run the garbage collection - esp. when the midlet code is pleading for it!
And what's more strange is how System.gc() will only have any effect if I implement it via a dedicated Command....
Cheers,
James
 
Michael Yuan
author
Ranch Hand
Posts: 1427
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, when you press that dedicated command button, the system dispatches events and that might trigger it to check the status of GC and run any pending requests. The bottom line is: the System.gc() behavior is entirely unpredictable in any Java runtime. So, do not count on it. Refactor your code to take less memory instead.
 
James Hodgkiss
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I set my canvas to null and run the gc (succesfully) it frees up an extra 60k of memory - so I can assume that is what is used by my canvas. Is 60k considered a lot for a canvas?
Are there any good optimisation tips for canvases in terms of memory usage? I've read that combining several images into one large image (then splitting it up later) is a good trick. Do you know any others?
Thanks,
James
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic