Skip to content

Commit 5120dfe

Browse files
committed
Update README.md
1 parent cecb0a0 commit 5120dfe

File tree

1 file changed

+62
-1
lines changed

1 file changed

+62
-1
lines changed

README.md

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# JavaSnippets
1+
# Java Snippets
22
Snippets of useful/interesting Java code
33

44
## Technology
@@ -27,3 +27,64 @@ Snippets of useful/interesting Java code
2727
+ Selection sort, heapsort, mergesort, quicksort, binary search
2828
+ Adjaceny matrix, adjacncy list
2929
+ Mutex, semaphore, deadlock, livelock, lock/monitor
30+
31+
# Garbage Collection Tuning
32+
33+
Some of my favorite articles on the subject include (if you are new to GC tuning you should read these first):
34+
35+
+ [Java SE 6 HotSpot Virtual Machine Garbage Collection Tuning](http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html)
36+
+ [How to Tune Java Garbage Collection](http://architects.dzone.com/articles/how-tune-java-garbage)
37+
+ [Garbage Collectors Available In JDK 1.7.0_04](http://www.fasterj.com/articles/oraclecollectors1.shtml)
38+
+ [1.4.1 Garbage collection algorithms](http://www.javaperformancetuning.com/news/qotm026.shtml)
39+
+ [Understanding CMS GC Logs](https://blogs.oracle.com/poonam/entry/understanding_cms_gc_logs)
40+
41+
The young and old generation use different types of algorithms for garbage collection. The young generation uses a copying collection algorithm that moves all the live object from one area to another, leaving the dead objects behind. The old generation uses a mark-and-sweep collection algorithm. Copy collection time is roughly proportional to the number of live objects, mark-and-sweep collection is roughly proportional to the size of the heap. This is why the young heap is small and collected frequently and the old heap is big and collected less frequently.
42+
43+
There are two major aspects to play with: the algorithm used (on both the young and old generation) and the amount of memory allocated.
44+
45+
### Algorithm
46+
47+
On a multicore machine the choice is between the parallel algorithm and the concurrent algorithm. Parallel means that during the stop-the-world pause the collector uses multiple threads to complete the job. Concurrent means that some of the work can be done whilst the application is running, therefore reducing the length of the stop-the-world pause. The important difference is:
48+
49+
+ Parallel: use when optimizing for throughput, therefore your system will be able to process more requests, but stop-the-world pauses will be more noticeable.
50+
+ Concurrent: use when optimizing for latency, therefore your system will produce more consistent, but slower results.
51+
52+
On all the systems I've worked on, consistency is more important so I normally use the concurrent algorithm. The concurrent algorithm only works on the old generation, but the parallel algorithm will be defaulted for the new generation. To enable the concurrent algorithm use the flag:
53+
54+
```
55+
-XX:+UseConcMarkSweepGC
56+
```
57+
58+
To enable the parallel algorithm I use the flags:
59+
60+
```
61+
-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy
62+
```
63+
64+
### Memory
65+
66+
Increasing the memory allocated will cause longer GC, but also mean less frequent runs. I usually find that allocating the minimum amount is usually the best strategy, because even though more GC collections will occur, they will be much faster. The start size and max size should be set to the same size:
67+
68+
```
69+
-Xmx512m -Xms512m
70+
```
71+
72+
### Debug Flags
73+
74+
I like to set the following:
75+
76+
```
77+
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:/home/user/gc.log
78+
```
79+
80+
To get even more details I add:
81+
82+
```
83+
-XX:+PrintTenuringDistribution -XX:+PrintHeapAtGC
84+
```
85+
86+
To check if a flag is set by default:
87+
88+
```
89+
java -XX:+PrintFlagsFinal | grep FLAG
90+
```

0 commit comments

Comments
 (0)