我如何知道我的应用程序运行的JVM是32位还是64位?具体来说,我可以在程序中使用哪些函数或属性来检测这一点?
当前回答
如果您使用的是JNA,您可以检查com.sun.jna.Native. net是否为JNA。POINTER_SIZE == 4(32位)或com.sun.jna.Native。指针大小== 8(64位)。
其他回答
对于Windows,您可以检查Java主位置。如果包含(x86),则为32位,否则为64位:
public static boolean is32Bit()
{
val javaHome = System.getProperty("java.home");
return javaHome.contains("(x86)");
}
public static boolean is64Bit()
{
return !is32Bit();
}
示例路径:
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
为什么只关心Windows解决方案呢?
如果你需要知道你在哪个位版本上运行,你可能会摆弄Windows上的本机代码,所以平台独立性是不可能的。
这是JNA用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;
}
}
如果你正在使用JNA,你可以使用thisPlatform.is64Bit()。
在Linux上,您可以使用以下两个命令之一来获取ELF头信息:
file {YOUR_JRE_LOCATION_HERE}/bin/java
o / p: ELF 64位LSB可执行文件,AMD x86-64,版本1 (SYSV),适用于GNU/Linux 2.4.0,动态链接(使用共享库),适用于GNU/Linux 2.4.0,未剥离
or
readelf -h {YOUR_JRE_LOCATION_HERE}/bin/java | grep 'Class'
o / p: 类 : ELF64
您可以使用JNI库。这将始终工作,并且独立于运行的JVM品牌。
Java代码:
package org.mytest;
public class NativeBinding
{
public static native int getRegisterWidth(); // returns 32 or 64
}
这是C代码:
#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;
}
推荐文章
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- Java Regex捕获组
- Openssl不被视为内部或外部命令
- 如何添加自定义方法到Spring Data JPA
- 如何在Ubuntu中设置Java环境路径
- 无法执行dex:在Eclipse中超过GC开销限制
- 有人能解释一下JPA和Hibernate中的mappedBy吗?
- 是什么导致JNI调用变慢?
- Java中的&和&&有什么区别?
- 使用Java的Collections.singletonList()?
- Maven使用多个src目录编译
- 导入时无法解析符号