Skip to main content

Garbage collection and -verbose:gc give no garbage collection output

7 replies [Last post]
demonduck
Offline
Joined: 2008-03-14
Points: 0

Using this applet param:

I get no garbage collection output.

I'm very careful in my applet to only use and reuse class and automatic variables. I don't create anything at runtime but I can't imagine the whole JVM being that frugal. I call System.gc() explicitly at specific times after user input -- dragging the mouse or keyboard input.

Is the JVM that good about not creating and nulling objects at runtime that I don't see anything? I'm doing a fair amount of computation for each frame. The frame rate is shown in the console. I use lots of transcendental functions in the Math package and use BufferStrategy and MemoryImageSource to draw. Am I not setting the params right or is there just no garbage collecting happening?

Here's the applet:

http://pancyl.com/DarkSnowCreek1.htm

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mbien
Offline
Joined: 2007-04-29
Points: 0

try to set xmx and xms to around 150m. Your applet uses 110m in mean.

But anyway there might be something wrong, i monitored your app till some young gcs fired and saw no output. Try starting your app directly without the webstart sandbox.

demonduck
Offline
Joined: 2008-03-14
Points: 0

I use a template for my HTML page and I just grab a lot of memory because of the way I can use my applet. I can load other large panos into the same applet via using JavaScript controls. I can suck up a lot of memory that way because I store state information and other stuff in static variables. It's all not too efficient right now so I grab lots of memory.

I didn't code my applet to be run as an application. Probably should have. Didn't think about it at the time. Too lazy to go back and add main() method. So it's pretty much in the sandbox.

I've never seen any gc related output in the console now that you mention it.

I'm going to try some other tests in a little while -- eating breakfast now..

After breakfast --

If I use -verbose:gc as a JVM argument in Eclipse, I can see messages from gc in stdout when I run the applet in the applet viewer. I think that is approximately what you suggested.

But I do not see any gc messages in the console either using the default gc or G1 with all the -XX args.

There are now two HTML pages that you can use:

http://pancyl.com/DarkSnowCreek1.htm

is set up to use G1

and

http://pancyl.com/DarkSnowCreek2.htm

uses only -verbose:gc and the default gc.

No messages from the gc in either case after click/drag the mouse. System.gc() is called when the mouse button is released.

Update:

If I use the Control Panel to set the JVM arguments to
those specified in my first message and then run my applet
locally, a DoS command window pops up and shows ONLY the garbage collector messages.

I think that -verbose:gc should use the Java Console.

That aside, it looks like that calling System.gc() explicitly at strategic times in my applet does help conserve memory resources. And that is important to do
on machines that are not running Plugin2 or are running
FF2 since those machines do not support the use of the
java_arguments param.

Here is some output I copied from the DoS command window:

http://pancyl.com/GarbageCollector.txt

[b]HOWEVER!!![/b]

If I run IE6 using Plugin2 [b]AND[/b] the arguments in the
java_arguments param are the same as the arguments I set
for the JVM in the Java Control Panel --

[b]THIS IS IMPORTANT! [/b]

Then the applet [b]FAILS!!![/b]

To be clear, duplicate arguments in both the java_arguments
param AND the JVM arguments set in the Java Control Panel
make the applet fail. This is probably a bug.

I trapped a stack trace and it's clear that the problem is that two sets of memory setting parameters cause both to be ignored.

Here is the output from the Java Console. Remember that I'm setting the memory limits like this:
-Xms384m -Xmx512m
But I'm setting them in both the java_arguments param and
the JVM arguments in the Java Control Panel. So they apparently cancel each other out because the memory that the Java Console shows is much less in fact it is the default
memory size:

PanGnomic v3.3
java.lang.OutOfMemoryError: Java heap space
at pangnomic.PanGnomicImageFetch.makeBufferedImage(Unknown Source)
at pangnomic.PanGnomicImageFetch.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
flushImage()...
Memory: 65,088K Free: 16,120K (24%) ... completed.

mbien
Offline
Joined: 2007-04-29
Points: 0

>>That aside, it looks like that calling System.gc() explicitly at strategic times in my applet does help conserve memory resources. And that is important to do
on machines that are not running Plugin2 or are running
FF2 since those machines do not support the use of the
java_arguments param.<<

explicit gc will almost certainly reduce your overall throughput and in worst case brake the VM's internal gc heuristics. There is no need to call the gc except in special situations like benchmarks or in app servers which have to clean rmi objects once in a hour.
If you really want to call it than call it e.g after everything was set up and is ready to render but not on user input like mouse drag (if i understood you correctly).

again system.gc causes a full stop independently of your chosen gc impl. The idea behind a generational GC is being lazy and sweep only on demand. Using the GC to constantly clean the heap of dead objects is very inefficient since it wasn't built for that. A full GC is automatically triggered when a new object does not fit into the free heap, if it still does not fit into the heap after GC an OOME is thrown.

This means explicit gcs won't help to prevent OOMEs (this is probably what you meant with 'conserve memory resources').

back on topic ;)
you could try this flag for a workaround(additional to the other flags):
-Xloggc:

demonduck
Offline
Joined: 2008-03-14
Points: 0

My applet has a wait state in it's event handler loop. I call System.gc() just before I wait() for user input. So it doesn't really impact throughput because the applet is idle. You can see that for yourself in the task manager.

And I was surprised to see just how much memory was used servicing a click/drag action by the user. I don't make any new objects in my applet while servicing user input but a lot of memory can be freed afterward. And if the applet is running in a non-plugin2 environment, the default memory available is between 65 and 90 meg. Not all that much when the image I'm showing can be 45meg. I can only show images that are half the size of available memory because of the way I do things internally. It's another long story. But that's not a lot of memory left.

I didn't know that a gc would be done if a new object wouldn't fit into the heap. That's useful info but I've seen sequential gc's each increase available memory so it seems to me that there could be a boundary situation where that mechanism might not prevent an OOME. One gc might not be enough. In fact one of the SUN guys suggested looping around a request for a large array just to be safe -- like in the old UNIX days.

And my applet can go full screen which means I have to have room for a large offscreen drawing area and a lot of supporting objects. Some monitors these days can be really big.

And there are so many different release levels out in the wild, it's hard to know what to depend on so I've taken to being a "belt and suspenders" programmer.

And remember -- it's an unsigned applet -- no file system access.....

linuxhippy
Offline
Joined: 2004-01-07
Points: 0

> I'm very careful in my applet to only use and reuse
> class and automatic variables. I don't create
> anything at runtime but I can't imagine the whole JVM
> being that frugal. I call System.gc() explicitly at
> specific times after user input -- dragging the mouse
> or keyboard input.
Usually System.gc() usually isn't a good idea, the JVM is pretty good to do the GC when it needs it.
So best is to let the JVM do its job, except you run into specific problems.

> The frame rate is shown in the console.
As far as I know JVM output is not redirected to the Java Console, only System.out is.
So I am pretty sure the JVM does garbage collections and print debugging output, however the output is not redirected into the console but lost somehwere ;)

- Clemens

demonduck
Offline
Joined: 2008-03-14
Points: 0

I've read somewhere that it's best to write "dumb" code and not try to manage the JVM too much. I guess that is appropriate for me to do in my applet and not call System.gc() -- doesn't seem to do much anyway.

I know stderr and stdout both go to the Java Console. I use them all the time.

After all the work done on the new plugin and the new garbage collector and the emphasis for Java finally turning toward the desktop, it seem like sending gc messages to the Java console would be appropriate.

You must be correct saying gc output is lost because I sure don't see any. That's too bad because it would be interesting to see.

mbien
Offline
Joined: 2007-04-29
Points: 0

do you see gc log output with the other gc impls.?

>..System.gc() -- doesn't seem to do much anyway.
it usually invokes a full gc over all generations...