Appendix A. JVM tuning

This appendix discusses ways to increase the performance of nondistributed Mahout-based applications by tuning the settings of the JVM. It’s not a guide to tuning Hadoop, which is a large topic in its own right. This tuning is relevant to nondistributed aspects of Mahout, which are almost entirely the recommender engine implementations. While the settings here are likely beneficial to any Java-based server process, the advice is specifically directed to those running nondistributed Mahout-based recommender engines.

When using a data set of substantial size—perhaps ten million preferences and up—it’ll be well worth tuning the JVM settings for performance. It’s mostly the heap-related (memory-related) settings that are important. Optimal settings depend on the operating system, available resources, architecture, and JVM, but the following JVM flag settings will establish a good starting point.

The flags listed in table A.1 are valid on all known Java 6 JVMs, which Mahout requires, with the exception of -XX:NewRatio, as explained in the table.

Table A.1. Key JVM tuning parameters for recommender engines

Parameter

Description

-Xmx This selects the maximum size that Java will allow the heap to grow to. For example, -Xmx512m indicates that the heap may grow to 512 MB.
-server Modern JVMs have two important flags, -client and -server, which select JVM settings broadly appropriate for short-running, small-footprint, client-side applications, and long-running, resource-intensive, server applications. The default depends on the JVM and environment. Obviously, -server is appropriate here.
-d32 and -d64 These request 32-bit and 64-bit mode, respectively. On a 64-bit machine, both are possible. While it’s typically best to let the JVM decide, selecting 32-bit mode will decrease memory requirements. Of course, 32-bit mode makes it impossible to use more than 2–3 GB of heap (depends on the JVM), but, when pushing this boundary, a small memory savings may be worthwhile. Selecting 32-bit mode on a 64-bit machine may incur a small performance penalty.
-XX:+NewRatio= Some heap space is always reserved for short-lived, temporary objects, and can never be used by more permanent data structures. Mahout runs lean: it creates few short-lived objects but consumes a lot of heap space with long-lived objects. The default proportion of the heap reserved for short-lived objects is generally too large and ends up being wasted needlessly. A setting of 12, for example, requests that only 1/12 of the heap be reserved for short-lived objects. Note that this setting appears to be specific to Sun JVMs only.
-XX:+UseParallelGC and -XX:+UseParallelOldGC This instructs the JVM to make better use of multiple processors or cores (common on even desktop computers today) by running garbage collection in parallel.

To demonstrate the effect of these JVM settings, we experiment with the code from listing 4.2 (in chapter 4). Let’s start with 32-bit client JVM defaults: -client -d32 -Xmx512m. These are JVM flags, not program flags, so they go before the program class name. On one modern 64-bit computer we used for testing, the load evaluation result indicates that it’s producing recommendations in about 425 ms and consuming 248 MB of heap in steady state. (Your timing results may vary, as may your exact heap size.)

What if we substitute -server for -client? If anything, it should increase performance. Memory requirements stay the same, but recommendation time drops to 192 ms. This shows how much more appropriate the server JVM tuning is for an application like this.

Now, change -d32 to -d64. You’ll encounter an OutOfMemoryError. You’ll probably need to allocate 768 MB to the heap, with -Xmx768m, to get it to run again. Recommendation time drops again to 142 ms. Not surprisingly, 64-bit mode is more efficient on a 64-bit machine. Steady-state memory requirements are about the same though: 256 MB. The 64-bit mode increases the memory consumed by objects and references, but by design, relatively few long-lived objects are created by Mahout’s recommender engine to begin with.

You may have noticed a discrepancy: why, if steady-state memory requirements are only about 256 MB, did the JVM fail due to lack of heap space when it had 512 MB available? Memory requirements peak at a higher level during construction of the in-memory data representation in the DataModel.

You should find that the -XX:+NewRatio=12 flag allows you to reduce heap size to about 640 MB.

Finally, try adding -XX:+UseParallelGC -XX:+UseParallelOldGC. Assuming more than one processor core is available, this will allow garbage collection work to proceed in parallel with the main computation. On our test machine, recommendation time drops to 126 ms. Compare that to the initial result of 425 ms.

Figure A.1 shows how, on a modern machine, improper JVM configuration can slow down performance by about 350 percent! Any serious deployment of a recommender engine must be properly tuned.

Figure A.1. Progressively better per-recommendation running times (in milliseconds) with various JVM tuning settings

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.16.177