28

I'm currently having problems with very long garbage collection times. please see the followig. My current setup is that I'm using a -Xms1g and -Xmx3g. my application is using java 1.4.2. I don't have any garbage collection flags set. by the looks of it, 3gb is not enough and I really have a lot of objects to garbage collect.

question:

should I change my garbage collection algorithm? what should i use? is it better to use -XX:+UseParallelGC or -XX:+UseConcMarkSweepGC

or should i use this combination

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC 

the ones occupying the memory are largely reports data and not cache data. also, the machine has 16gb memory and I plan to increase the heap to 8gb.

What are the difference between the two options as I still find it hard to understand. the machine has multiple processors. I can take hits of up to 5 seconds but 30 to 70 seconds is really hard.

Thanks for the help.

 Line 151493: [14/Jan/2012:11:47:48] WARNING ( 8710): CORE3283: stderr: [GC 1632936K->1020739K(2050552K), 1.2462436 secs] Line 157710: [14/Jan/2012:11:53:38] WARNING ( 8710): CORE3283: stderr: [GC 1670531K->1058755K(2050552K), 1.1555375 secs] Line 163840: [14/Jan/2012:12:00:42] WARNING ( 8710): CORE3283: stderr: [GC 1708547K->1097282K(2050552K), 1.1503118 secs] Line 169811: [14/Jan/2012:12:08:02] WARNING ( 8710): CORE3283: stderr: [GC 1747074K->1133764K(2050552K), 1.1017273 secs] Line 175879: [14/Jan/2012:12:14:18] WARNING ( 8710): CORE3283: stderr: [GC 1783556K->1173103K(2050552K), 1.2060946 secs] Line 176606: [14/Jan/2012:12:15:42] WARNING ( 8710): CORE3283: stderr: [Full GC 1265571K->1124875K(2050552K), 25.0670316 secs] Line 184755: [14/Jan/2012:12:25:53] WARNING ( 8710): CORE3283: stderr: [GC 2007435K->1176457K(2784880K), 1.2483770 secs] Line 193087: [14/Jan/2012:12:37:09] WARNING ( 8710): CORE3283: stderr: [GC 2059017K->1224285K(2784880K), 1.4739291 secs] Line 201377: [14/Jan/2012:12:51:08] WARNING ( 8710): CORE3283: stderr: [Full GC 2106845K->1215242K(2784880K), 30.4016208 secs] xaa:1: [11/Oct/2011:16:00:28] WARNING (17125): CORE3283: stderr: [Full GC 3114936K->2985477K(3114944K), 53.0468651 secs] --> garbage collection occurring too often as noticed in the time. garbage being collected is quite low and if you would notice is quite close the the heap size. during the 53 seconds, this is equivalent to a pause. xaa:2087: [11/Oct/2011:16:01:35] WARNING (17125): CORE3283: stderr: [Full GC 3114943K->2991338K(3114944K), 58.3776291 secs] xaa:3897: [11/Oct/2011:16:02:33] WARNING (17125): CORE3283: stderr: [Full GC 3114940K->2997077K(3114944K), 55.3197974 secs] xaa:5597: [11/Oct/2011:16:03:00] WARNING (17125): CORE3283: stderr: [Full GC[Unloading class sun.reflect.GeneratedConstructorAccessor119] xaa:7936: [11/Oct/2011:16:04:36] WARNING (17125): CORE3283: stderr: [Full GC 3114938K->3004947K(3114944K), 55.5269911 secs] xaa:9070: [11/Oct/2011:16:05:53] WARNING (17125): CORE3283: stderr: [Full GC 3114937K->3012793K(3114944K), 70.6993328 secs] 
1

5 Answers 5

7

Since you have extremenly long GC pauses, it's don't think that changing GC algorithm would help.

Note that it's highly suspicious that you have only full collections. Perhaps you need to increase the size of young generation and/or survivor space.

See also:

Sign up to request clarification or add additional context in comments.

2 Comments

ya, it only happens when reports are being generated. these are objects coming from the database and they have really large values. I was wondering if there was anyway that I could get by with this. in scenario 2, I think the heap size is really lacking that's why we plan to increase it, for scenario 1, heap is still available. gc is around 25 to 30 seconds.
sorry bout that, i wasn't able to include the other gc in it. included it now for first scenario.
4

Your heap is too small. The pause is so large because it's busy repeatedly scanning the entire heap desperately looking for anything to collect.

You need to do 1 or possibly more of the following;

  • find and fix a memory leak
  • tune the application to use less memory
  • configure the JVM is use a bigger heap

Are you tied to 1.4.2 for some reason? GC implementations really have moved on since then so you should consider upgrading if possible. I realise this may be a non trivial undertaking but it's worth considering anyway.

5 Comments

actually, it only happens when the users are starting to generate large reports and we really can't control. the reports are really large. currently, 1.4.2 is the server we are in, the process to migrate is there but we need to make do of what we can for now.
for scenario 1, i still have availble heap since my max heap is 3gb but still the garbage collection is too long.
If generating large reports is part of normal operation then your heap is simply too small. You need to do some proper benchmarking to tune this though and the output of that effort will be, at least partially, redundant if you move to a java6 or java7 jvm. You don't want to do the same job twice if you can help it.
for scenario 1, you need to collect more data about the shape of the heap. Flags you'd need to look at are PrintTenuringDistribution, verbose:gc, -Xloggc:gc.log, PrintGCDetails and PrintGCTimeStamps. Once you have this info then people can advise on sensible tuning steps that might give immediate benefit. Over 1s for a young collection is enormous after all.
fwiw the default collector, iirc, in 1.4 was a single threaded serial collector. Simply adding -XX:+UseParallelGC will almost certainly give you a substantial cut in STW time in the young collection. Note that you would have to switch to CMS to improve the tenured collector as there is no paralleloldgc in 1.4 as far as I recall. Therefore a good strategy might be a much bigger heap and the throughput collector. However a bigger heap means that when a tenured collection happens, it could be really long. Also bear in mind CMS needs a bigger heap than the parallel collector to work.
1

If you have high survival rate, your heap may be too large. The larger the heap, the longer the JVM can go without GC'ing, so once it hits, it has so much more to move around.

Comments

1

Step 1:

  1. Make sure that you have set enough memory for your application.
  2. Make sure that you don't have memory leaks in your application. Eclipse Memory Analyzer Tool or visualvm will help you to identify leaks in your application.

Step 2:

If you don't have any issues with Step 1 with respect to memory leaks, refer to oracle documentation page on use cases for specific garbage collection algorithm in "Java Garbage Collectors" section and gctuning article.

Since you have decided to configure larger heaps (>= 8 GB), G1GC should work fine for you. Refer to this related SE question on fine tuning key parameters:

Java 7 (JDK 7) garbage collection and documentation on G1

Comments

0

You must upgrade to at least Java 1.7. Java 1.4 is very unsupported.

Support for Java 1.4 ended 22 years ago!

Generally, old java code should run just fine on newer versions. In my experience, a JAR file compiled by Java 1.8 runs on Java 21 without problem. Java 1.4 code should run on Java 8 for sure.

In my experience, newer versions of Java also have vastly improved garbage collectors and handle memory much, much better than older versions.

Make sure your program always closes resources after opening them.

*Never, ever* forget to invoke close when the File, Stream, Clip, or other resource is no longer being accessed.

You should definitely try out VisualVM.

It is a free, open-source tool that allows you to monitor any running Java application.

Do not set -Xmx unless you need to, it prevents your app from using RAM it might need.

If you don't really care about RAM usage, set -Xms to a large value. Java generally runs better with more RAM. Allocating RAM at startup by increasing the value of -Xms should increase perfromance

I recommend reading the Java HotSpot Virtual Machine Garbage Collection Tuning Guide it contains information about the different garbage collectors and their use cases.

To see what's going on with the garbage collector, you may turn on GC logging. Don't forget to add -Xlog:async!

The flags I recommend are: -Xms3G -Xnoclassgc

You may also try: -XX:+AlwaysPreTouch -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=86 --XX:G1HeapRegionSize=8M

Note: If VisualVM does not run, use visualvm --jdkhome <path>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.