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]
Ravindra babu
  • 42,401
  • 8
  • 208
  • 194
grassbl8d
  • 1,989
  • 4
  • 22
  • 30
  • 1
    Here is link which may be helpful for you http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html. The collectors are specific to 1.5, concept for parllel and concurrent sweep might be same in 1.4. – kosa Jan 25 '12 at 16:02

4 Answers4

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:

axtavt
  • 228,184
  • 37
  • 489
  • 472
  • 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. – grassbl8d Jan 25 '12 at 16:03
  • sorry bout that, i wasn't able to include the other gc in it. included it now for first scenario. – grassbl8d Jan 25 '12 at 16:08
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.

Matt
  • 7,811
  • 3
  • 26
  • 56
  • 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. – grassbl8d Jan 25 '12 at 16:52
  • for scenario 1, i still have availble heap since my max heap is 3gb but still the garbage collection is too long. – grassbl8d Jan 25 '12 at 16:54
  • 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. – Matt Jan 25 '12 at 20:55
  • 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. – Matt Jan 25 '12 at 21:01
  • 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. – Matt Jan 25 '12 at 21:05
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

Community
  • 1
  • 1
Ravindra babu
  • 42,401
  • 8
  • 208
  • 194
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.

nilskp
  • 2,868
  • 1
  • 28
  • 33