Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
java [2012/12/04 23:34] 2a01:260:4121:1:1e6f:65ff:fe38:dc56 |
java [2012/12/07 12:29] (current) a |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Java (JVM) tips and tricks ====== | + | ====== Java (jvm) tips and tricks ====== |
+ | |||
+ | |||
+ | ===== Enviroment settings ===== | ||
+ | |||
+ | ==== Linux (with multiple java enviroments) ==== | ||
+ | |||
+ | '' | ||
+ | | ||
+ | | ||
+ | |||
+ | |||
+ | |||
+ | ===== Tuning | ||
+ | |||
+ | {{ : | ||
^ switch ^ description ^ | ^ switch ^ description ^ | ||
- | | **-Xmx** | + | | **-Xmx** |
- | | **-Xms** | + | | **-Xms** |
+ | | **-Xmn** | **Size of the heap for the young generation** - young generation represents all the objects which have a short life of time. Young generation objects are allocated in a specific location into the heap, where the garbage collector will pass often. All new objects are created into the young generation region (called " | ||
+ | | **-Xss** | ** Stack size for each thread ** - This sets size of preallocated stack for each thread. If you set this too low your program will crash with StackOverflowExceptions. Setting this too high will cause excessive memory usage - this amount of memory gets allocated for **each** thread in the JVM. The default for most JVMs is 512k. Note: When increasing this number on Linux, you will probably have to also increase native stack size to same amount with " | ||
+ | | || | ||
+ | | **-XX: | ||
+ | | **-XX: | ||
+ | | **-XX: | ||
+ | | **-XX: | ||
+ | | **-XX: | ||
+ | | **-XX: | ||
+ | |||
+ | |||
+ | <note important> | ||
+ | **A nice gotcha...** \\ | ||
+ | Full-heap major garbage collection **will not** run until the tenured part of heap is full. This means if you have heap size (Xmx) of 1024MB with 750MB of heap allocated and your program has only 250MB of objects actually reachable (" | ||
+ | |||
+ | This is by design - it improves performance. Don't give JVM more heap space than you're actually willing to lose. | ||
+ | </ | ||
+ | |||
+ | <note tip> | ||
+ | * It is good practice with server-side Java applications like Resin to set the minimum **'' | ||
+ | * For efficient garbage collection, the **'' | ||
+ | </ | ||
+ | |||
+ | ==== Choosing the garbage collector ==== | ||
+ | |||
+ | In Sun/Oracle JVM you have a choice of three garbage collectors, each built for different use case. | ||
+ | |||
+ | * **Serial collector** - single-threaded, | ||
+ | * **Parallel collector** - does small passes in parallel, **+XX: | ||
+ | * **Concurrent collector** - does most of the collection in other threads, minimizes pauses, **+XX: | ||
+ | |||
+ | === Serial collector === | ||
+ | |||
+ | Is the efficient (no intra-thread communication) of the three. Stops the world while running collection. | ||
+ | |||
+ | **Best for**: applications running on single-core, | ||
+ | |||
+ | === Parallel collector === | ||
+ | |||
+ | Does minor collection (eden) in parallel thus greatly reducing garbage collection overhead on multi-core machines. With **+XX: | ||
+ | |||
+ | **Best for**: applications with medium to large datasets (100MB+), applications that run on multi-core machines, application where peak throughput is the priority and pauses of 1 sec are acceptable. | ||
+ | |||
+ | === Concurrent collector === | ||
+ | |||
+ | Does most of it's work concurrently while other application threads are still running. It keeps garbage collection pauses the shortest possible at the expense of total garbage collection time and increased memory usage. The maximum response time is achieved at the cost of total application throughput so this GC may reduce total application performance at the expense of maximizing response time. | ||
+ | |||
+ | **Best for**: applications with medium to large datasets (100MB+) which require minimal response time (with pauses required to be less than 1 sec). | ||
+ | |||
+ | <note important> | ||
+ | ** Concurrent GC on machines with 2 cores ** | ||
+ | |||
+ | During each concurrent GC phase a whole core is pinned to the GC and is not available to the rest of the application. Due to long running passes of concurrent GC this may not be desireable on machines with only two cores. | ||
+ | |||
+ | Enabling **incremental mode** for concurrent GC will cause the GC to do each pass in several phasses while relinquishing CPU to the application inbetween. This causes the core to be available to the application for more time at the expense of further prolonging the GC passes. Incremental mode is enabled with **-XX: | ||
+ | </ | ||
+ | |||
+ | [[http:// | ||
+ | |||
+ | ===== Good/best practices ===== | ||
+ | |||
+ | 1. OpenJDK 1.6 and 1.7 may (as of now, 6. 12. 2012) still be unstable in stressful production environments leading up to segmentation faults and unintended behaviour. Use Sun/Oracle JVM for maximum stability and performance. | ||
+ | |||
+ | |||
+ | ===== Examples ===== | ||
+ | |||
+ | tying to limit jvm to ~2G of RAM (java x86_64) | ||
+ | java -Xms512m -Xmx2G -XX: | ||
+ | |||
+ | java (i386) | ||
+ | java -Xms1400m -Xmx2G -XX: | ||
+ | |||
+ | ===== Troubleshooting ===== | ||
+ | |||
+ | === Resolving java.lang.OutOfMemoryError: | ||
+ | if you get an error like: | ||
+ | |||
+ | | ||
+ | |||
+ | The PermGen space is used for things that do not change (or change often). e.g. Java classes. | ||
+ | |||
+ | To increase the PermGen space use something like: **-XX: | ||
+ | |||
+ | (Note that Xmx is separate from the PermGen space, so increasing Xmx will not help with the PermGen errors). \\ | ||
+ | **The PermGen memory in addition to the Xmx memory. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||