简体   繁体   中英

32 OR 64 BIT for the JVM?

While reading this book over here .

I can see the following section, which says:

32 OR 64 BIT? If you have a 32-bit operating system, then you must use a 32-bit version of the JVM. If you have a 64-bit operating system, then you can choose to use either the 32- or 64-bit version of Java. Don't assume that just because you have a 64-bit operating system, you must also use a 64-bit version of Java.

If the size of your heap will be less than about 3 GB, the 32-bit version of Java will be faster and have a smaller footprint. This is because the memory references within the JVM will be only 32-bits, and manipulating those memory references is less expensive than manipulating 64-bit references (even if you have a 64-bit CPU). The 32-bit references also use less memory.

Chapter 8 discusses compressed oops, which is a way that the JVM can use 32-bit addresses even within the 64-bit JVM. However, even with that optimization, the 64-bit JVM will have a larger footprint because the native code it uses will still have 64-bit addresses.

The downside to the 32-bit JVM is that the total process size must be less than 4GB (3GB on some versions of Windows, and 3.5GB on some old versions of Linux). That includes the heap, permgen, and the native code and native memory the JVM uses. Programs that make extensive use of long or double variables will be slower on a 32-bit JVM because they cannot use the CPU's 64-bit registers, though that is a very exceptional case.

Programs that fit within a 32-bit address space will run anywhere between 5% and 20% faster in a 32-bit JVM than a similarly-configured 64-bit JVM. The stock batching program discussed earlier in this chapter, for example, is 20% faster when run on a 32-bit JVM on my desktop.

The lines says 32-bit will be faster for lesser heap size (less than 3GB). If this is true, I want to know the reason behind it, what makes 32-bit JVM is faster?

I'm skeptical of the author's claim that using the 32-bit version of the JVM will give a 5% to 20% performance improvement. However, I don't use Java much so I don't know for sure. But in order to investigate this claims I looked at the some of the results from SPEC.

I searched for the SPECjEnterprise2010 results and the highest score for an x86-64 architecture was an Oracle system that used a 64-bit version of the JVM .

I also looked at SPECjvm2008 in case these smaller workloads might benefit from the 32-bit architecture. But again the best performing x86-64 system, this time from Huawei, was using the 64-bit version of the JVM.

If the 32-bit version of the JVM really was better I would expect that people submitting their SPEC results would have selected that when tuning their workloads (but I could be wrong).

I don't doubt that there are some workloads where the 32-bit version of the JVM will outperform the 64-bit version. As others have noted it uses more memory for addresses. However, the x86-64 architecture has more registers available and I suspect that the 64-bit mode of operation is where most of the optimization work is focused.

System performance has many components, and I don't think that the 32-bit version of the JVM will necessarily outperform the 64-bit version (for one this this will only matter for CPU bound workloads). I'd say that if you got to this point in the performance tuning process that you would want to check your own workload for the two different options, and use the outcome of your own tests for making a decision rather than assuming that using the 32-bit is better than 64-bit because of saving memory space for addresses as a rule of thumb, because there are other factors that could be more important than this.

It is more a matter of general performance. If you have a recent 64 bit processor and plenty of unused memory, the only possible gain using JVM 32 instead of JVM 64 would be that some loops could fully fit in cache with 32 bits addresses and not with 64 bits ones leading to less main memory accesses with a 32 bits JVM. I really cannot evaluate the gain, but except in very special cases I doubt it reaches 5 to 20 % - note I only doubt, not sure ...

But if you are using a resources limited system, eventually because you want to optimize your hardware and run many virtual machines on it, a 32 bits JVM will use far less memory than a 64 bits one. It will leave more free memory to other applications and to the system thus avoiding swapping and allowing the system to better cache disk IO.

IMHO, there is no general rule. I would just use following rule of thumb : if when the JVM and all other applications are running, the system still has enough memory for caching IO, I would use a 64 bits JVM, and a 32 bits one in opposite case.

Of course above only has sense if the Java application by itself do not need a lot of memory imposing the use of a 64 bits JVM - and eventually adding more memory to the system if necessary, because memory is not that expensive nowadays

There is no simple answer and the best thing to do is to try it out for your specific application. But you should keep in mind, that there are lots of other options, eg regarding JIT, Garbage Collection algorithm, RAM limits, that might have an impact bigger than the choice of the architecture so you have to include these in your measurements.

If you ever ask that question, in other words have the choice , it implies that you are already running on a 64 Bit System having a 32 Bit mode (with acceptable performance, ie no software emulation) which is most likely AMD64 aka x86-64.

On such systems Oracle's JVM supports “compressed oops” which means using 32 Bit references within the Java heap as long as the maximum heap does not exceed 32 GB (if it does, I doubt that using 32 Bit is a valid choice for that application). It might still consume more RAM compared to the 32 Bit JVM as some components still require using 64 Bit pointers but these are usually not the performance relevant parts of an application.

Note that for the AMD64 aka x86-64 architecture using the 64 Bit mode implies more than just changing pointer size. Note only allows it using 64 Bit per register, it also has more usable registers. It's really a different architecture implemented within the same chip and depending on your application, enabling it may be a great improvement.

But as said, testing it with your real application is the only valid way of getting the correct answer.

If you intend to use one of the Oracle VMs the question turns more into whether you want to use the client or the server JIT since there is no client JIT available for any 64 bit CPU from Oracle yet.

A server VM is available for both 32 and 64 bit CPUs and the performance differences of the server VMs on x86/AMD64 CPUs are rather small (in my experience it's less then +/-5% on Windows or Linux), although the 64 bit VM typically needs about 20% more memory.

If your application needs a heap memory size of more than about 1.3GB you will have to use a 64 bit server VM as the 32 bit VMs from Oracle won't start with heap sizes greater than that (on Linux the limit is slightly higher).

The main advantage of the of the client JIT is that it has a much faster startup time. You can do quite a lot of serious work in less then 100ms with this VM while the server VM takes more than a second only to get started even with tiered compilation turned on. The client VM also needs significantly less memory than the server VM and can benefit form class data sharing between multiple VM instances on the same computer.

The server VM on the other hand tends to be able to execute computational intensive code considerably faster. The actual performance differences vary widely depending on the code you execute but can be between about -10% and +200%. Usually it's at least 30% faster for anything that takes more than a few hundred milliseconds to run.

You can tweak both JITs with various options to make them behave more similar but you still get the fast startup time only with the client VM and the highest execution speeds only with the server VM.

So I'd recommend to use the 64 bit server VM for everything when you have enough memory available and don't care about the startup time penalty. The 32 bit client VM is great for smaller GUI applications but especially for small command line tools that take less than a second to execute on average or might need to run multiple times concurrently on the same computer.

32 bit memory addresses are smaller. That alone likely leads to better caching, locality of reference etc.

32 bit address less memory space max theoretical limit is 4GB but in practice it is 1.3GB in Windows System. You can address some what more (300 to 400 MB) more on Linux kernel. For more details use http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit (Heap Space Memory)

The 64bit uses higher bits to address. So overall memory consumption also higher. There is option to use Compressed Memory pointer. Read more about the same at http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#compressedOop

The reason why 64 bit is slower is because of large Garbage collection pauses. Building up more heap means there is more work to be done by GC while cleaning it up from unused objects. What it means in real life is that you have to be extra cautious when building heaps larger than 12-16GB. Without fine tuning and measuring you can easily introduce full GC pauses spanning several minutes.

One argument to go for 64 bit is that 32 bit server hardware is pretty rare these days. As a consequence, there are not that many people using 32 bit software on servers. The primary reason 32 bit jvms still exists at all is to support 32 bit client software for older 32 bit systems as well as applets, which run via plugin in 32 bit browsers.

So, if there are exotic bugs lurking in the 32 bit version, you might be the first to find out. These would be the type of bugs that would be less visible on desktop systems and more visible in long running server side software. Think mysterious crashes after a few weeks/days. Memory leaks, etc.

So, if you are deploying on a server, pretty much go for 64 bit unless you have a very strong reason not to. There are a lot snakeoil solutions floating around when it comes to Java's memory usage and garbage collection. So, I would be wary of using that as an argument either way, unless you can back it up with some solid metrics. In my experience, java engineers that know how to properly tune a jvm are actually pretty rare and most seem to just randomly copy paste stuff around on the JVM_ARGS until it sort of works. Most of them end up shooting themselves in the foot with solutions that are either not optimal, no longer appropriate for the JVM they use, or actively harmful. Jvm tuning is a bit of a black art. Best not to mess too much with it unless you know what you are doing.

For client systems, go 32 bit if you need to support applets or older desktop systems. Eg windows shipped 32 bit versions of their OS until recently and lots of apps on windows and osx continue to be 32 bit. Mostly you shouldn't have to choose and in any case and you can leave this choice to the user.

For people worried about address size, the 64 bit version can do pointer compression for heaps smaller than 32GB. You need to (and probably want to) turn this on in the JVM args: -XX:+UseCompressedOops. .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM