Which object types contribute most to the garbage? How much garbage does the given dump contain? The questions that are most important when analyzing heap dumps for GC optimizations are: It also means that you can run the tool on any machine, including big and powerful, but "headless" machines in a data center. The advantage of this approach is that you can view the results of analysis anywhere at any time and share it with others easily. The tool generates a report with all the collected information in the HTML format. Unlike most other tools, JXRay analyzes a heap dump right away for a large number of common problems, such as duplicate strings and other objects, suboptimal data structures, boxed numbers, etc. The commercial tools include the general-purpose Java profilers: JProfiler and YourKit, as well as one tool built specifically for heap dump analysis called JXRay. The most popular open-source tool is Eclipse MAT there is also VisualVM and some less powerful, lesser-known tools. There are a number of heap dump analysis tools available, both open-source and commercial. To obtain a heap dump with garbage (a "full" dump), one should invoke the JDK jmap utility without the -live flag. And the most comprehensive way of memory analysis is by taking a heap dump.Ī heap dump is essentially a full snapshot of the running JVM's heap. You should use a memory analysis tool instead. But in any real-life application, such guessing just won't work. A question remains, though: How do we know which objects to optimize? In our benchmark, it was straightforward because, after all, we had only two types of objects created in large quantities. Furthermore, improvements made in the code work well in the long term, regardless of the GC type and possible changes in the JVM, hardware, etc. How Do We Know Which Object to Optimize?īy now, it should be clear that by making selective, often very small and low-effort optimizations in the code, we may be able to improve GC performance of the application better, and much more reliably, than if we spend a lot of time tuning the garbage collector. Getting rid of creation and GCing of a vast number of small objects clearly improves performance. The simple benchmark below models, very roughly, an application that reads incoming data (strings), performs some calculations and stores the key-value pairs in the cache: /** Base class for all benchmarks */Ībstract class AbstractTest extends Thread Īnd rerun it with the same parameters as before, it now takes just 12 sec! That's twice faster than the previous version and 7 times faster than the original version. To illustrate that, let's consider the following example. Is it possible to improve GC performance in some alternative way: not by tuning GC, but by making your app fundamentally more GC-friendly? It turns out that often the answer is yes. XX:+UseParNewGC -XX:MaxTenuringThreshold=2 -XX:SurvivorRatio=8 -XX:ParGCCardsPerStrideChunk=32768 -XX:CMSParallelRemarkEnabled -XX:+ParallelRefProcEnabled -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly And (what a surprise!) at that point, it may be really hard to remember why each of the flags in the combination like the one below is there, and what its effect was supposed to be: If any of these components changes in the future, the GC may suddenly perform much worse. Need help choosing the right GC? Check out this Worse, hyper-tuning GC makes it tightly coupled with your current heap size, number of CPUs, and workload patterns. And GC tuning, beyond a few most obvious and efficient flags, often becomes a black art where each new change brings a smaller improvement. The heap may already be close to the total memory available. When asked: "What would you do if your Java app experiences long GC pauses?" - most people would answer: "increase the heap size and/or tune the garbage collector." That works in many but not all situations. Is the performance improvement really worth it? I saw the source code of ArrayList, and the fact that they are iterating over the list of elements to assign null to them, made me wonder why they couldn't clear the memory by a quicker technique.The best way to optimize garbage collection is NOT by tuning it.A cursory glance at new ArrayList() might make a person think an array is newly being initialized there. Somehow, clear() lets the maintainer know that the array is being cleared. Although I feel it's nice, I felt it decreases readability.He agreed when I asked if he was doing it to let the garbage collector take care of it. When my colleague saw that line, he changed it to myArray = new ArrayList(). When not needing them to be in memory any longer, I use myArray.clear() to free up the memory. I work with large HashMap's and ArrayLists.
0 Comments
Leave a Reply. |