JRE 32bit vs 64bit
Asked Answered
P

5

14

I've been using Java for a while now, and my typical ritual of setting up a new dev machine requires the norm of downloading and installing the latest JDK from Oracle's site.

This prompted an unusual question today, does it matter if I use the 32bit or 64bit JRE bundle?

From thinking back on it, I've installed both versions before and my normal toolchain plugs happily in (Eclipse). In my day-to-day programming, I do not recall ever having to change something or think about something in a different way just because I was using the 64bit JRE (or targetting the 64bit JRE for that respect).

From my understanding of 64bit vs. 32bit - it really boils down to how the numbers are stored underneath the covers... and I do know that int is a 32 bits and long is 64 bits... same with float being 32 bits and double is 64 bits -- so is it just that Java has abstracted even this subtlety away, and perhaps has been "64 bit compatible" all along?

I'm sure I'm missing something here besides not being able to install a 64 bit JRE onto a 32 bit system.

Plebeian answered 24/6, 2013 at 22:5 Comment(4)
With a 32-bit JVM you are limited to -Xmx < 4GB, but it on 64-bit the only limit is hardware/virtual memory.Greyhound
@JimGarrison I think this is also further dependent on the OS too. On Windows with a 32bit JRE I think the max heap is somewhere < 2GB.Dipper
Windows is even more restricted: #1435279.Vyner
@wumpz: I think you're talking about 32-bit Windows, not 32-bit JVM on 64-bit Windows. You definitely want to use a 64-bit OS if you have more than 2GB or so of physical RAM, because it makes the OS less efficient if it can't just map all the memory at once into kernel address space, and instead has to play tricks to map different pages when needed.Anastomosis
E
24

64-bit vs. 32-bit really boils down to the size of object references, not the size of numbers.

In 32-bit mode, references are four bytes, allowing the JVM to uniquely address 2^32 bytes of memory. This is the reason 32-bit JVMs are limited to a maximum heap size of 4GB (in reality, the limit is smaller due to other JVM and OS overhead, and differs depending on the OS).

In 64-bit mode, references are (surprise) eight bytes, allowing the JVM to uniquely address 2^64 bytes of memory, which should be enough for anybody. JVM heap sizes (specified with -Xmx) in 64-bit mode can be huge.

But 64-bit mode comes with a cost: references are double the size, increasing memory consumption. This is why Oracle introduced "Compressed oops". With compressed oops enabled (which I believe is now the default), object references are shrunk to four bytes, with the caveat that the heap is limited to four billion objects (and 32GB Xmx). Compressed oops are not free: there is a small computational cost to achieve this big reduction in memory consumption.

As a personal preference, I always run the 64-bit JVM at home. The CPU is x64 capable, the OS is too, so I like the JVM to run in 64-bit mode as well.

Erumpent answered 25/6, 2013 at 0:26 Comment(3)
Freshly started Netbeans with my set of projects uses 600MB on x32 Java8, same thing started on x64 JVM uses 1180MB - twice more. That's why me personal preference is - use x32 JVM unless memory usage goes roughly beyond -Xmx1200, this is the largest heap size JVM is able to allocated (with slight differrence depending on the host OS).Fredenburg
Actually it's slightly more than 1200 MB, could be up to like 3-3.5G oracle.com/technetwork/java/…Undefined
Compressed oops have been the default since pretty much forever (well at least 5 years). On top of that, there are several "modes" of compressed oops, depending on the heap size range, so for the same size of heaps (~2GB or less) that you'd be able to use 32-bits, you don't pay much cost at all to use compressed oops (no scaling needed, the oops can be used directly with the high bits zero). So 64-bit is close to being strictly better.Perigee
L
5

As you note, primitive numeric types in Java are well-defined.

However, the choice between 32-bit and 64-bit JVMs can matter if your Java application is using native-code libraries, which may be built for use in a 32-bit application, a 64-bit application, or both.

If you have native libraries that support only 32-bit applications, you either need to use a 32-bit JVM, or build 64-bit versions of the libraries.

Ledeen answered 24/6, 2013 at 22:10 Comment(1)
as a rule of dumbs, develop with 32 bit JRE and run in 64 bit JRE?Clintonclintonia
T
3

Depending on context, for local development I will always use a 64-bit JDK. Primarily because I would likely need the whole memory space for builds and the IDE.

That being said for integration to production, I would recommend 32-bit if it is possible. Why?

For some Java EE servers that are licensed for production use, it would depend on some factors like which machine how many cores etc. For WebSphere Liberty Profile specifically, you are also limited to 2GB.

64-bit JREs would take up slightly more memory and if you're trying to constrain it to something like 2GB or better yet 2x 1GB cluster you would have more flex space to work around in without paying a cent.

From https://plumbr.eu/blog/java/should-i-use-32-or-64-bit-jvm

Problem 1: 30-50% of more heap is required on 64-bit. Why so? Mainly because of the memory layout in 64-bit architecture. First of all – object headers are 12 bytes on 64-bit JVM. Secondly, object references can be either 4 bytes or 8 bytes, depending on JVM flags and the size of the heap. This definitely adds some overhead compared to the 8 bytes on headers on 32-bit and 4 bytes on references. You can also dig into one of our earlier posts for more information about calculating the memory consumption of an object.

Problem 2: Longer 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. In applications where latency is not crucial and you can optimize for throughput only this might be OK, but on most cases this might become a showstopper.

To limit your impact for your Java EE environment, offload parts of it to other microservices such as ElasticSearch for search, Hazelcast for caching, your database for data storage and keep your Java EE server to host your application core itself rather than running the services inside it.

Thrombosis answered 1/6, 2017 at 17:6 Comment(0)
K
2

I think there are two main differences to consider. One has been mentioned here but not the other.

On the one hand, as other mentioned, the memory and data types. 32-bits and 64-bits JVMs use different native data type sizes and memory-address spaces.

  • 64-bits JVMs can allocate (can use) more memory than the 32-bits ones.
  • 64-bits use native datatypes with more capacity but occupy more space. Because that, the same Object may occupy more space too.
  • For JVMs which the Garbage Collector (GC) freezes the machine, the 64-bits versions may be slower because the GC must check bigger heaps/objects and it takes more time.
  • There is an IBM presentation explaining these differences.

And on the other hand, the supported native libraries. Java programs that use JNI to access native libraries require different versions depending on the type of JVM.

  • 32-bits JVMs use 32-bits native libraries and 64-bits JVMs use 64bits libraries.
  • That means that, if your program uses libraries that rely on native code such as SWT, you will need different versions of them. Note in the SWT download page, there are different versions for Linux/Windows 32- and 64-bits. Note that there are different versions of Eclipse (each one with a different version of SWT) for 32- and 64-bits.
  • Some applications, such as Alloy, are packaged with 32-bits native libraries. They fail with 64-bit JVMs. You can solve these problems just downloading the corresponding 64-bits native libraries and configuring the JNI appropriately.
Kings answered 29/7, 2017 at 3:52 Comment(7)
x86-64 also has more registers than ia32, so the actual asm generated by a JIT compiler can be more efficient (fewer spills/reloads to/from memory). It's also a more orthogonal compiler-target, since the low byte of all 16 registers is directly accessible. I'm not sure if JIT has much use for RIP-relative addressing, but it does make position-independent code easier/more efficient than in 32-bit mode.Anastomosis
Are there any 64-bit JVMs that use the x32 ABI? (32-bit pointers in long mode?) That would have all the advantages of both (small pointers -> smaller cache footprint for GC, while still doing 64-bit integer ops with a single instruction.)Anastomosis
The Oracle JVM includes an option to use "compressed oridinary object pointers". Basically, the JVM can use 32-bit values as pointers to objects in memory instead of 64-bit values. You may check the UseCompressedOops flag.Kings
Neat. That's not quite as efficient as x32, where limiting all pointers to be in the low 32 bits of address space lets you use them by just zero-extending them. Java goes for some extra overhead in "decoding" (left shift by 3 and add to heap base). But fortunately an x86 addressing mode can do [base + index*8], so it should be pretty efficient to dereference, and only take an extra instruction to compare with a non-encoded pointer. And of course it costs extra when encoding. Anyway, looks like a sensible tradeoff for Java, since they don't want to limit the heap to 4GB.Anastomosis
What do you mean by "native datatypes"? Do you mean Java data types like int, long, char and so on? Or are you referring to some native C++ code inside the JVM itself? The latter is mostly irrelevant since the vast majority of your memory use will usually be part of the Java heap whose data types mostly haven't changed sizes (with a caveat about references). Most important native data types (which, really) probably don't change sizes too: certainly if you're doing a lot of off-heap stuff or have native code you can choose to keep the data types the same size.Perigee
On top of that references are also going to be same size due to "compressed oops" which is the default, for any heap size where you can make a direct comparison. So 64-bit is pretty much strictly better. Sure, you might note that if you need greater than 32 GB heaps you'll have 64-bit references, but if you need that big of a heap 32-bits is out of consideration by definition, since it has a max heap size of ~2 GB.Perigee
Primitive data types (such as int, long or char) work mostly equal in both types of JVMs. Their size do not change. The size only changes for references. Operations on such types are atomic for any one with less than 32 bits. Some operations will be not atomic in 32-bit JVMs when the data is greater than 32 bits. However, these differences may be neglible. -- Differences occur mainly in objects or libraries that interact with native libraries. -- for the size of primitive data types, you may check #9512336Kings
P
2

Do I need to understand the difference between 32-bit JVM and 64-bit JVM?

If you aren’t building a performance critical application, you don’t have to understand the difference. The subtle difference between 32-bit JVM and 64-bit JVM wouldn’t make much difference to your application. You can skip reading further

Does 64-bit JVM perform better than 32-bit JVM?

Most of us think 64-bit is bigger than 32-bit, thus 64-bit JVM performance will be better than 32-bit JVM performance. Unfortunately, it’s not the case. 64-bit JVM can have a small performance degradation than 32-bit JVM. Below is the excerpt from Oracle JDK documentation regarding 64-bit JVM performance:

“Generally, the benefits of being able to address larger amounts of memory come with a small performance loss in 64-bit VMs versus running the same application on a 32-bit VM.

The performance difference comparing an application running on a 64-bit platform versus a 32-bit platform on SPARC is on the order of 10-20% degradation when you move to a 64-bit VM. On AMD64 and EM64T platforms this difference ranges from 0-15% depending on the amount of pointer accessing your application performs.”

Does 32 bit JVM or 64 bit JVM matter anymore.

What are the things to consider when migrating from 32-bit JVM to 64-bit JVM? a. GC Pause times

The primary reason to migrate from 32-bit JVM to 64-bit JVM is to attain large heap size (i.e. -Xmx). When you increase heap size, automatically your GC pause times will start to go high, because now there is more garbage in the memory to clear up. You need to do proper GC tuning before doing the migration, otherwise your application can experience several seconds to few minutes pause time.

b. Native Library

If your application is using Java Native Interface (JNI) to access native libraries, then you need to upgrade the native libraries as well. Because 32-bit JVM can use only 32-bit native library. Similarly, 64-bit JVM can use only 64-bit native library.

Properly answered 18/6, 2019 at 1:2 Comment(4)
x86 32 vs. 64-bit is special because 64-bit mode has twice as many integer and FP registers for the JIT compiler to use. For other ISAs (like SPARC), that's not the case: 32-bit SPARC already had enough registers so it's just wider pointers, and 64-bit integers with a single register / single instruction. So outside of x86, the only benefit is for code that uses 64-bit integers, or code that needs more than 4GB of memory. But it's a much less obvious tradeoff on x86, where larger pointers still hurt (cache footprint / mem bandwidth) but more registers for more efficient code helps.Anastomosis
dup javaprogrammingforums.com/java-programming-tutorials/…Summersummerhouse
@BhargavRao: What was the point of removing a mention of a specific tool (GCeasy) from this answer? Was this flagged as spam / self-promotion? Your change didn't have an edit message and it looked like a sensible suggestion.Anastomosis
@PeterCordes, Your guess is correct. I've sent a note to the poster, they can edit it in once they provide self-attribution.Cutback

© 2022 - 2024 — McMap. All rights reserved.