605

How can I tell if the JVM in which my application runs is 32 bit or 64-bit? Specifically, what functions or properties I can used to detect this within the program?

Hearen
  • 7,420
  • 4
  • 53
  • 63
BobMcGee
  • 19,824
  • 10
  • 45
  • 57
  • 4
    Just out of curiosity, why would you need to know the natural size of the system? Details such as this are abstracted away in Java, so you shouldn't (in theory, at least) have to know them. – Patrick Niedzielski Jan 14 '10 at 04:29
  • 3
    It lets me roughly estimate the memory requirements for objects due to pointers. Curiosity too -- seemed like there should be a way, but I'd never heard of it. – BobMcGee Jan 14 '10 at 18:33
  • 90
    This "detail" is not abstracted away when interacting with the Java Native Interface. 32-bit DLLs can't be loaded with a 64-bit JVM (and vice versa). So this is quite essential information for anyone using JNI. It's a pity that there seems to be no portable way to obtain this info. One way is to first try loading a 32-bit version of the DLL, and if it fails, try the 64-bit version, etc. Ugly! – Joonas Pulakka Apr 30 '10 at 07:17
  • 12
    Another situation where discerning between 32 or 64 bit JVMs is important is for mapped files. On 32 bit systems only 2GB can be mapped, so it's important to map and unmap file segments accordingly so that this limit is not exceeded, while on 64 bit jvms the limit is much, much, much higher. – Simone Gianni Sep 09 '12 at 21:07
  • @simonegianni wouldn't that make such a mapping the perfect test? – Thorbjørn Ravn Andersen Jul 09 '13 at 22:32
  • 1
    Note that there is a vast difference between a _human_ being able to tell, and the _program_ being able to tell. Humanly readable strings are rarely defined rigidly so relying on them makes you subtly vendor dependent. – Thorbjørn Ravn Andersen Jul 11 '13 at 12:26
  • 2
    It's really nice to be able to choose the numerical algorithm that will be fastest on the machine in question. – dfeuer Apr 22 '14 at 18:09
  • Also note that both the detection mechanisms and the object size is vendor dependent. – Thorbjørn Ravn Andersen Jun 27 '16 at 14:22
  • Note that java does some tricks such that "ordinary object pointers" are 32-bit on 64-bit JVMs with typical heap limits. – plugwash Jul 28 '16 at 16:46
  • 1
    @PatrickNiedzielski Another situation where discerning between 32 or 64 bit JVMs is of paramount importance is when a Java program must start an external executable, for which both versions exist. Like writing Selenium tests, where the right browser driver must be started. And the same need exists for discerning the operating system. I'm sure one can think of several more cases where something that is supposed to be "abstracted away" is not. – SantiBailors Dec 13 '16 at 11:49

13 Answers13

758

For certain versions of Java, you can check the bitness of the JVM from the command line with the flags -d32 and -d64.

$ java -help
...
    -d32          use a 32-bit data model if available
    -d64          use a 64-bit data model if available

To check for a 64-bit JVM, run:

$ java -d64 -version

If it's not a 64-bit JVM, you'll get this:

Error: This Java instance does not support a 64-bit JVM.
Please install the desired version.

Similarly, to check for a 32-bit JVM, run:

$ java -d32 -version

If it's not a 32-bit JVM, you'll get this:

Error: This Java instance does not support a 32-bit JVM.
Please install the desired version.

These flags were added in Java 7, deprecated in Java 9, removed in Java 10, and no longer available on modern versions of Java.

MultiplyByZer0
  • 6,302
  • 3
  • 32
  • 48
gpampara
  • 11,989
  • 3
  • 27
  • 26
  • 3
    Although this is good to know, it's not useful b/c I need to run it from outside the program or use java options to start a new process. – BobMcGee Jan 14 '10 at 05:06
  • 1
    Sorry I, completely misread the question. Within Java itself, the correct manner would be as described by codadict – gpampara Jan 14 '10 at 05:48
  • 15
    Exactly what I was looking for. And you can run `java -d32 -version` to verify you are not running 32-bit. Both wish work on `Win7`. – Xonatron Feb 02 '12 at 20:34
  • 36
    I am on Windows 7, and I get 'unrecognized option' error from `java -d32 -version` *and also from* `java -d64 -version`. – ely Apr 20 '12 at 20:29
  • 1
    I am able to use this command to determine the bits of my VM, thanks! CGuo@CGUO-E8420 ~ $ java -d64 -version Error: This Java instance does not support a 64-bit JVM. Please install the desired version. CGuo@CGUO-E8420 ~ $ java -d32 -version java version "1.7.0_09" Java(TM) SE Runtime Environment (build 1.7.0_09-b05) Java HotSpot(TM) Client VM (build 23.5-b02, mixed mode) – charles Dec 11 '12 at 18:11
  • I am on windows 7 and the lowercase -d64 appeared to work while the uppercase -D64 appeared to have no effect – user1445967 Jan 20 '14 at 17:53
  • For me neither -D64 nor -D32 is showing `This Java instance does not support a 64-bit JVM. Please install the desired version.'. – user3164187 Jun 10 '14 at 12:11
  • 44
    Do not use "-D64", for that does something completely different. It defines a system property called "64". This is definitely not what is wanted here. – Jonathan Headland Jul 30 '14 at 12:00
  • 10
    The -d32 or -d64 flags will only work for a Java 7 or greater. – darrenmc Aug 08 '14 at 10:41
  • Reading and trying again and again, and end up with sad news. I have JDK 6 – Sarz Dec 04 '14 at 07:06
  • 2
    No -version argument is required. You can use `java -d64`. – Developer Marius Žilėnas Mar 15 '16 at 08:01
  • @darrenmc FYI, one of my old linux server running JDK 1.5.0_17, it works for both -d32 & -d64. The output is: "Running a 64-bit JVM is not supported on this platform." for d64, while the d32 option is regular version output. – Tomofumi Mar 22 '17 at 02:30
  • 1
    @Willmore No, it is not correct. If you have 64 bit JVM and run `java -d32`, it detects error of not supported. But, if you run `java -d64`, it complains about missing parameters and `-version` is needed. – WesternGun Aug 04 '17 at 09:58
  • java -d64 -version. Worked on Windows 10, thank you. – Amar HR Aug 06 '18 at 04:38
  • 7
    This argument was removed in Java 9, see [JDK-8168010](https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8168010). Additionally it might not satisfy "from within a program" reliably, given that Solaris supported both pre JDK8 and therefore you could likely currently be running with a 32 bit data model, but `java -d64 -version` returned with exit code 0. – Marcono1234 Sep 12 '18 at 07:50
336

You retrieve the system property that marks the bitness of this JVM with:

System.getProperty("sun.arch.data.model");

Possible results are:

  • "32" – 32-bit JVM
  • "64" – 64-bit JVM
  • "unknown" – Unknown JVM

As described in the HotSpot FAQ:

When writing Java code, how do I distinguish between 32 and 64-bit operation?

There's no public API that allows you to distinguish between 32 and 64-bit operation. Think of 64-bit as just another platform in the write once, run anywhere tradition. However, if you'd like to write code which is platform specific (shame on you), the system property sun.arch.data.model has the value "32", "64", or "unknown".

An example where this could be necessary is if your Java code depends on native libraries, and you need to determine whether to load the 32- or 64-bit version of the libraries on startup.

Community
  • 1
  • 1
codaddict
  • 445,704
  • 82
  • 492
  • 529
  • Is this defined by the Java spec to work under all JVMs, or is it Hotspot-specific? – BobMcGee Jan 14 '10 at 04:14
  • 23
    I wouldn't expect to find `sun.*` system properties with an IBM JVM. In other words, it's not portable. – Pascal Thivent Jan 14 '10 at 23:19
  • 1
    Is this still valid now that Java is owned by Oracle? I am running an environment-auditor that will run pre-deploy of our application. We need to verify that the 64-bit production boxes had 64-bit Java installed on them since we don't manage these machines. I need to make sure this still works and will continue to work moving forward with Oracle. – Jesse Webb Aug 12 '10 at 16:36
  • 8
    How can you tell from the command line? If you are running 32-bit or 64-bit? Just curious. – Xonatron Feb 02 '12 at 20:33
  • 20
    Why is the accepted answer Sun-dependent? "os.arch" will accomplish the same thing without having to use proprietary sun packages. – arkon May 24 '12 at 10:38
  • 8
    @b1naryatr0phy, does os.arch report on the Operating System, or the JVM? I often run 32-bit JVM on my 64-bit workstation, for development purposes. – skiphoppy Aug 08 '12 at 17:19
  • 8
    This property is supported on IBM JVMs, but not on GCJ. See http://stackoverflow.com/questions/807263/how-do-i-detect-which-kind-of-jre-is-installed-32bit-vs-64bit – Emmanuel Bourg Nov 09 '12 at 13:13
  • 1
    For logging and benchmarking the type of VM is pretty important as well. So stating it is useful *only* for dependence on native libraries is incorrect, in my opinion. – Maarten Bodewes Aug 31 '14 at 16:49
  • This is a useful answer, but @gpampara's should be the accepted one. – bonh Jun 05 '15 at 19:22
  • 3
    As GCJ is as dead as a doornail, what it does and doesn't support is of no interest. – user207421 Aug 18 '16 at 03:19
200

Just type java -version in your console.

If a 64 bit version is running, you'll get a message like:

java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)

A 32 bit version will show something similar to:

java version "1.6.0_41"
Java(TM) SE Runtime Environment (build 1.6.0_41-b02)
Java HotSpot(TM) Client VM (build 20.14-b01, mixed mode, sharing)

Note Client instead of 64-Bit Server in the third line. The Client/Server part is irrelevant, it's the absence of the 64-Bit that matters.

If multiple Java versions are installed on your system, navigate to the /bin folder of the Java version you want to check, and type java -version there.

Sergei Tachenov
  • 24,345
  • 8
  • 57
  • 73
Sedat Kilinc
  • 2,843
  • 1
  • 22
  • 20
36

I installed 32-bit JVM and retried it again, looks like the following does tell you JVM bitness, not OS arch:

System.getProperty("os.arch");
#
# on a 64-bit Linux box:
# "x86" when using 32-bit JVM
# "amd64" when using 64-bit JVM

This was tested against both SUN and IBM JVM (32 and 64-bit). Clearly, the system property is not just the operating system arch.

Hearen
  • 7,420
  • 4
  • 53
  • 63
bryantsai
  • 3,405
  • 1
  • 30
  • 30
  • Yeah. It gives x86, etc. Not quite the same thing, since I'm not sure if it gives "x64" for x86-64 running in 64-bit rather than 32-bit. – BobMcGee Jan 14 '10 at 04:11
  • 3
    @codaddict, looks like it is JVM bitness indeed. – bryantsai Jan 14 '10 at 23:14
  • 21
    @codaddict That is completely false (and I have no idea why six ppl have voted that comment up.) "os.arch" is designed to return the JVM version. Test it out for yourself and god help you if you're actually relying on this for OS detection. – arkon May 24 '12 at 10:36
  • @b1naryatr0phy, never mind my comment to you on the other answer to this question. Thanks! :) – skiphoppy Aug 08 '12 at 17:20
  • 6
    `os.arch` has many possible values, it's difficult to tell if it's 32 or 64 bits. See http://lopica.sourceforge.net/os.html – Emmanuel Bourg Nov 09 '12 at 13:15
  • 2
    This is a string intended for human eyes and without a strict definition of valid values, relying on this is not a good idea - write code that checks actual functionality instead. – Thorbjørn Ravn Andersen Jul 09 '13 at 22:34
  • it's amd64 not xmd64 – sunnychan77 Mar 28 '18 at 07:12
15

Complementary info:

On a running process you may use (at least with some recent Sun JDK5/6 versions):

$ /opt/java1.5/bin/jinfo -sysprops 14680 | grep sun.arch.data.model
Attaching to process ID 14680, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 1.5.0_16-b02
sun.arch.data.model = 32

where 14680 is PID of jvm running the application. "os.arch" works too.

Also other scenarios are supported:

jinfo [ option ] pid
jinfo [ option ] executable core
jinfo [ option ] [server-id@]remote-hostname-or-IP 

However consider also this note:

"NOTE - This utility is unsupported and may or may not be available in future versions of the JDK. In Windows Systems where dbgent.dll is not present, 'Debugging Tools for Windows' needs to be installed to have these tools working. Also the PATH environment variable should contain the location of jvm.dll used by the target process or the location from which the Crash Dump file was produced."

dim
  • 1,697
  • 2
  • 13
  • 21
7

On Linux, you can get ELF header information by using either of the following two commands:

file {YOUR_JRE_LOCATION_HERE}/bin/java

o/p: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), for GNU/Linux 2.4.0, not stripped

or

readelf -h {YOUR_JRE_LOCATION_HERE}/bin/java | grep 'Class'

o/p: Class: ELF64

jawsnnn
  • 314
  • 2
  • 11
7

If you are using JNA, you can check whether com.sun.jna.Native.POINTER_SIZE == 4 (32 bit) or com.sun.jna.Native.POINTER_SIZE == 8 (64 bit).

roottraveller
  • 7,942
  • 7
  • 60
  • 65
Anthony Hayward
  • 2,164
  • 21
  • 17
  • This is clever but accessing the pointer size is significantly slower than the other solutions here (it needs some time to initialize). – BullyWiiPlaza Aug 07 '18 at 20:44
4

If you're using JNA, you can do thisPlatform.is64Bit().

1

This is the way JNA solves this with Platform.is64Bit() (https://github.com/java-native-access/jna/blob/master/src/com/sun/jna/Platform.java)

 public static final boolean is64Bit() {
        String model = System.getProperty("sun.arch.data.model",
                                          System.getProperty("com.ibm.vm.bitmode"));
        if (model != null) {
            return "64".equals(model);
        }
        if ("x86-64".equals(ARCH)
            || "ia64".equals(ARCH)
            || "ppc64".equals(ARCH) || "ppc64le".equals(ARCH)
            || "sparcv9".equals(ARCH)
            || "mips64".equals(ARCH) || "mips64el".equals(ARCH)
            || "amd64".equals(ARCH)
            || "aarch64".equals(ARCH)) {
            return true;
        }
        return Native.POINTER_SIZE == 8;
}

ARCH = getCanonicalArchitecture(System.getProperty("os.arch"), osType);

static String getCanonicalArchitecture(String arch, int platform) {
        arch = arch.toLowerCase().trim();
        if ("powerpc".equals(arch)) {
            arch = "ppc";
        }
        else if ("powerpc64".equals(arch)) {
            arch = "ppc64";
        }
        else if ("i386".equals(arch) || "i686".equals(arch)) {
            arch = "x86";
        }
        else if ("x86_64".equals(arch) || "amd64".equals(arch)) {
            arch = "x86-64";
        }
        // Work around OpenJDK mis-reporting os.arch
        // https://bugs.openjdk.java.net/browse/JDK-8073139
        if ("ppc64".equals(arch) && "little".equals(System.getProperty("sun.cpu.endian"))) {
            arch = "ppc64le";
        }
        // Map arm to armel if the binary is running as softfloat build
        if("arm".equals(arch) && platform == Platform.LINUX && isSoftFloat()) {
            arch = "armel";
        }

        return arch;
    }

static {
        String osName = System.getProperty("os.name");
        if (osName.startsWith("Linux")) {
            if ("dalvik".equals(System.getProperty("java.vm.name").toLowerCase())) {
                osType = ANDROID;
                // Native libraries on android must be bundled with the APK
                System.setProperty("jna.nounpack", "true");
            }
            else {
                osType = LINUX;
            }
        }
        else if (osName.startsWith("AIX")) {
            osType = AIX;
        }
        else if (osName.startsWith("Mac") || osName.startsWith("Darwin")) {
            osType = MAC;
        }
        else if (osName.startsWith("Windows CE")) {
            osType = WINDOWSCE;
        }
        else if (osName.startsWith("Windows")) {
            osType = WINDOWS;
        }
        else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) {
            osType = SOLARIS;
        }
        else if (osName.startsWith("FreeBSD")) {
            osType = FREEBSD;
        }
        else if (osName.startsWith("OpenBSD")) {
            osType = OPENBSD;
        }
        else if (osName.equalsIgnoreCase("gnu")) {
            osType = GNU;
        }
        else if (osName.equalsIgnoreCase("gnu/kfreebsd")) {
            osType = KFREEBSD;
        }
        else if (osName.equalsIgnoreCase("netbsd")) {
            osType = NETBSD;
        }
        else {
            osType = UNSPECIFIED;
        }
}
Fabian Knapp
  • 1,342
  • 13
  • 27
0

You can use a JNI library. This will always work and is independent of the running JVM brand.

Java code:

package org.mytest;

public class NativeBinding
{
    public static native int getRegisterWidth(); // returns 32 or 64
}

And this is the C code:

#include <jni.h>

// will return register width (32 or 64)
extern "C" JNIEXPORT jint JNICALL
Java_org_mytest_NativeBinding_getRegisterWidth(JNIEnv*, jclass)
{
    return sizeof(void*) * 8;
}
zomega
  • 1,538
  • 8
  • 26
-1

Under Windows 7 in the "Control Panel" under "Programs | Programs and Features" the 64-bit variants of JRE & JDK are listed with "64-bit" in parentheses (e.g. "Java SE Development Kit 7 Update 65 (64-Bit)"), while for the 32-bit variants the variant is not mentioned in parentheses (e.g. just "Java SE Development Kit 8 Update 60").

user1364368
  • 1,474
  • 1
  • 16
  • 22
-3

To get the version of JVM currently running the program

System.out.println(Runtime.class.getPackage().getImplementationVersion());
Zuko
  • 2,764
  • 30
  • 30
-3

For Windows, you can check the Java home location. If it contains (x86) it is 32-bit otherwise 64-bit:

public static boolean is32Bit()
{
    val javaHome = System.getProperty("java.home");
    return javaHome.contains("(x86)");
}

public static boolean is64Bit()
{
    return !is32Bit();
}

Example paths:

C:\Program Files (x86)\Java\jdk1.8.0_181\bin\java.exe # 32-bit
C:\Program Files\Java\jdk-10.0.2\bin\java.exe # 64-bit

Why care about a Windows only solution?

If you need to know which bit version you're running on, you're likely fiddling around with native code on Windows so platform-independence is out of the window anyway.

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
  • 1
    This is not a good idea, since the path can be chosen individually when installing Java. The absence of "(x86)" in the installation path says absolutely nothing about whether Java is available in 32/64bit version. – André Aug 21 '20 at 07:31
  • @André: Fair enough but 99% of all users would install to the default locations anyway. Maybe instead query the `java` or `javac` utility and see if certain `32-Bit` exclusive command line switches work or the `java -version` output includes something like `64-Bit` – BullyWiiPlaza Aug 21 '20 at 14:07
  • It's very unreliable. – Alexey Ivanov May 21 '21 at 14:17