612 Stimmen

Wie kann ich feststellen, ob ich in einer 64-Bit-JVM oder einer 32-Bit-JVM arbeite (innerhalb eines Programms)?

Wie kann ich feststellen, ob die JVM, in der meine Anwendung läuft, 32-Bit oder 64-Bit ist? Welche Funktionen oder Eigenschaften kann ich verwenden, um dies innerhalb des Programms zu erkennen?

4 Stimmen

Nur aus reiner Neugierde: Warum müssen Sie die natürliche Größe des Systems kennen? Details wie diese sind in Java abstrahiert, so dass Sie sie (zumindest theoretisch) nicht kennen müssen.

3 Stimmen

Damit kann ich den Speicherbedarf für Objekte aufgrund von Zeigern grob abschätzen. Neugier auch - schien, wie es sollte ein Weg sein, aber ich hatte noch nie davon gehört.

13 Stimmen

Eine weitere Situation, in der es wichtig ist, zwischen 32- und 64-Bit-JVMs zu unterscheiden, ist bei gemappten Dateien. Auf 32-Bit-Systemen können nur 2 GB abgebildet werden. Daher ist es wichtig, Dateisegmente entsprechend zuzuordnen und die Zuordnung aufzuheben, damit diese Grenze nicht überschritten wird, während die Grenze auf 64-Bit-JVMs viel, viel, viel höher ist.

8voto

Anthony Hayward Punkte 1855

Wenn Sie JNA verwenden, können Sie prüfen, ob com.sun.jna.Native.POINTER_SIZE == 4 (32 Bit) oder com.sun.jna.Native.POINTER_SIZE == 8 (64 Bit).

7voto

jawsnnn Punkte 195

Unter Linux können Sie ELF-Header-Informationen mit einem der beiden folgenden Befehle abrufen:

file {YOUR_JRE_LOCATION_HERE}/bin/java

o/p: ELF Ausführbare 64-Bit-LSB-Datei AMD x86-64, Version 1 (SYSV), für GNU/Linux 2.4.0, dynamisch gelinkt (verwendet gemeinsam genutzte Bibliotheken), für GNU/Linux 2.4.0, nicht gestrippt

oder

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

o/p: Klasse: ELF 64

6voto

鹞之神乐 Punkte 41

Wenn Sie JNA verwenden, können Sie Folgendes tun Platform.is64Bit() .

1voto

Fabian Knapp Punkte 1355

So löst JNA das Problem mit 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;
        }
}

0voto

somega Punkte 841

Sie können eine JNI-Bibliothek verwenden. Dies wird immer funktionieren und ist unabhängig von der laufenden JVM-Marke.

Java-Code:

package org.mytest;

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

Und dies ist der 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;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X