2009-04-30 54 views

回答

0

在Linux上,我的(JAVA)VM报告java.vm.name =的HotSpot的Java(TM)64位服务器VM。对于系统的javadoc声明System.getProperty始终拥有该值,但都在sun.arch.data.model沉默。

不幸的是,他们没有指定的系统属性会这么一些其他JVM可能只是报告java.vm.name =埃德加什么。

BTW,通过“安装在系统上”,我假设你的意思是“当前正在运行的JVM”?

System.getProperty("os.arch"); 

的“操作系统”的部分似乎是有点用词不当,或者是原设计者没有想到的JVM到:

45

的JVM架构中使用可使用“os.arch”属性检索在没有写入的体系结构上运行。返回值似乎是inconsistent

的NetBeans安装团队JVM的tackling the issue VS OS架构。报价:

64位:Java和系统

履带作为Issue 143434

目前我们使用JVM的64位,以 确定系统(并且因此 Platform.getHardwareArch())是64位的 与否。这绝对是错误的,因为 有可能在64位系统上运行32位JVM上的 。在32位JVM上运行时,我们应该找到一个 解决方案来检查操作系统真正的64位 。

  • 用于Windows它可以使用WindowsRegistry.IsWow64Process()
  • 用于Linux做 - 通过检查 'UNAME -m/-p' == x86_64的
  • 用于Solaris它可以使用例如进行“的isainfo -b”
  • 为Mac OSX它不能使用UNAME参数来完成,或许可以通过 64位二进制 创建和平台上执行的解决... (不幸的是,这并不工作:( 我创建的二进制只有x86_64的 和PPC64拱,这是成功的老虎执行 ..)
  • 的通用Unix的支持 - 目前尚不清楚,以及...可能检查 为同'uname -m/-p'/'getconf LONG_BIT'并将它与一些 可能的64位值(x86_64,x64, amd64,ia64)进行比较
  • 0123从不同的JVM和

样品性能都在64位的Ubuntu 8.0上运行。4:

32位IBM 1.5:

java.vendor=IBM Corporation 
java.vendor.url=http://www.ibm.com/ 
java.version=1.5.0 
java.vm.info=J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20061001 (JIT enabled) 
J9VM - 20060915_08260_lHdSMR 
JIT - 20060908_1811_r8 
GC - 20060906_AA 
java.vm.name=IBM J9 VM 
java.vm.specification.name=Java Virtual Machine Specification 
java.vm.specification.vendor=Sun Microsystems Inc. 
java.vm.specification.version=1.0 
java.vm.vendor=IBM Corporation 
java.vm.version=2.3 
os.arch=x86 
os.name=Linux 
os.version=2.6.24-23-generic 
sun.arch.data.model=32 

64日1.6:

java.vendor=Sun Microsystems Inc. 
java.vendor.url=http://java.sun.com/ 
java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport.cgi 
java.version=1.6.0_05 
java.vm.info=mixed mode 
java.vm.name=Java HotSpot(TM) 64-Bit Server VM 
java.vm.specification.name=Java Virtual Machine Specification 
java.vm.specification.vendor=Sun Microsystems Inc. 
java.vm.specification.version=1.0 
java.vm.vendor=Sun Microsystems Inc. 
java.vm.version=10.0-b19 
os.arch=amd64 
os.name=Linux 
os.version=2.6.24-23-generic 
sun.arch.data.model=64 

64位GNU 1.5:

java.vendor=Free Software Foundation, Inc. 
java.vendor.url=http://gcc.gnu.org/java/ 
java.version=1.5.0 
java.vm.info=GNU libgcj 4.2.4 (Ubuntu 4.2.4-1ubuntu3) 
java.vm.name=GNU libgcj 
java.vm.specification.name=Java(tm) Virtual Machine Specification 
java.vm.specification.vendor=Sun Microsystems Inc. 
java.vm.specification.version=1.0 
java.vm.vendor=Free Software Foundation, Inc. 
java.vm.version=4.2.4 (Ubuntu 4.2.4-1ubuntu3) 
os.arch=x86_64 
os.name=Linux 
os.version=2.6.24-23-generic 

(GNU版本不报告“的太阳。 arch.data.model“属性;推测其他JVM也不会)

0

系统上可能有32位和64位的JVM,并且其中有很多。

如果你已经有每个受支持的平台的DLL - 考虑制作一个小的可执行文件链接和运行,以便测试平台是否支持给定的功能。如果可执行文件链接并运行,则可以安装相应的共享库。

-5

下面的代码检查machineType字段中可执行任何窗口以确定它是否是32或64位:

public class ExeDetect 
{ 
    public static void main(String[] args) throws Exception { 
    File x64 = new File("C:/Program Files/Java/jre1.6.0_04/bin/java.exe"); 
    File x86 = new File("C:/Program Files (x86)/Java/jre1.6.0/bin/java.exe"); 
    System.out.println(is64Bit(x64)); 
    System.out.println(is64Bit(x86)); 
    } 

    public static boolean is64Bit(File exe) throws IOException { 
    InputStream is = new FileInputStream(exe); 
    int magic = is.read() | is.read() << 8; 
    if(magic != 0x5A4D) 
     throw new IOException("Invalid Exe"); 
    for(int i = 0; i < 58; i++) is.read(); // skip until pe offset 
    int address = is.read() | is.read() << 8 | 
     is.read() << 16 | is.read() << 24; 
    for(int i = 0; i < address - 60; i++) is.read(); // skip until pe header+4 
    int machineType = is.read() | is.read() << 8; 
    return machineType == 0x8664; 
    } 
} 

注意,代码已被压缩为简洁...

+1

注意,代码尽快打破在用户没有按不使用非常相同的版本... – 2009-12-03 15:00:19

+2

-1可怕的方法。没有跨平台。硬编码版本。 – Tomas 2011-03-31 13:56:59

+1

这是在Windows上检测64位可执行文件的通用方法。没有特定的jre版本。 – 2011-04-23 01:31:56

2
import sun.misc.*; 

import java.lang.reflect.*; 

public class UnsafeTest { 
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { 
    Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); 
    unsafeField.setAccessible(true); 
    Unsafe unsafe = (Unsafe) unsafeField.get(null); 
    System.out.println(unsafe.addressSize()); 
    } 
} 
6

我正在使用NSIS和Launch4j来包装Java桌面应用程序。所以我不仅需要检测任何JRE,而且Launch4j会使用它的搜索算法。唯一有意义的方法是在NSIS安装程序中运行一个简短的Java程序。这里是在Java:

 

    public class DetectJVM { 
     private static final String keys [] = { 
      "sun.arch.data.model", 
      "com.ibm.vm.bitmode", 
      "os.arch", 
     }; 
     public static void main (String [] args) { 
      boolean print = args.length > 0 && "-print".equals(args[0]); 
      for (String key : keys) { 
       String property = System.getProperty(key); 
       if (print) System.out.println(key + "=" + property); 
       if (property != null) { 
        int errCode = (property.indexOf("64") >= 0) ? 64 : 32; 
        if (print) System.out.println("err code=" + errCode); 
        System.exit(errCode); 
       } 
      } 
     } 
    } 

总结这与Launch4J。使用GUI标题类型,但也设置为true。否则,错误代码将会丢失。 (我把所有这一切在我的Netbeans的Ant构建脚本

下面是使用它的匹配NSIS代码:

 

File ... ; unpack files including detectjvm.exe. 
ClearErrors 
ExecWait '"$INSTDIR\detectjvm.exe"' $0 
IfErrors DetectExecError 
IntCmp $0 0 DetectError DetectError DoneDetect 
DetectExecError: 
    StrCpy $0 "exec error" 
DetectError: 
    MessageBox MB_OK "Could not determine JVM architecture ($0). Assuming 32-bit." 
    Goto NotX64 
DoneDetect: 
IntCmp $0 64 X64 NotX64 NotX64 
X64: 
    File ... 64-bit AMD DLLs. 
    Goto DoneX64 
NotX64: 
    File ... 32-bit x86 DLLs. 
DoneX64: 
Delete $INSTDIR\detectjvm.exe 

这已通过Vista中运行良好的一个非常大的品种从WinXP的机器,没有SP和Win7与32位和64位的所有SP

请注意,在我的NSIS脚本中,我正在使用现有软件包检查JVM是否已安装,并首先执行该操作,因此默认的32位只有在JVM安装出错的情况下才会发生选择,在这种情况下,您复制的DLL集合无论如何都不会影响

希望这对某人有帮助。

+0

这是一个非常有用的解决方法。问题是,如果用户的64位机器没有与JVM一起安装?剧本将做出错误的假设。 – 2011-11-04 05:25:00

+0

请注意,对于我的情况,我需要使用Launch4J将其添加到控制台。 – 2011-11-28 01:51:00

3

在编写Java代码时,我该如何区分32位和64位操作?

http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#64bit_detection

有没有公共API,可以让你32和 64位操作进行区分。把64位看作只是编写一次的另一个平台,可以在任何地方运行。但是,如果您想编写特定于平台的代码(对您不利),则系统属性 sun.arch.data.model的值为“32”,“64”或“unknown”。

+0

正如ThorbjørnRavn Andersen在另一篇文章中所说的,32位JVM在64位操作系统上运行良好。如果您担心JVM位宽而不是操作系统位宽(假设您正在热点JVM上运行......),请使用sun.arch.data.model属性 – billsimons 2011-01-15 03:49:08

+0

位问题不是因为的Java代码本身,但由于封装,我们的软件附带。假设如下:如果客户尝试安装我们的64位软件版本,但他只安装了32位Java;他被告知... – user97629 2011-01-24 10:29:32

-1

如果您有要检查的.exe路径,可以使用this answer。基本上它只是查看.exe文件中的标题,并告诉你它是否在Windows上是64位或32位。

+0

彼得·史密斯的答案是相同的逻辑,但做对 – Massimo 2017-07-02 18:27:23

-1
java -version 

对于一个64位的Java版本,它会打印:

java version "1.8.0_92" 
Java(TM) SE Runtime Environment (build 1.8.0_92-b14) 
Java HotSpot(TM) ***64-Bit*** Server VM (build 25.92-b14, mixed mode) 

对于32位,它会只是

java version "1.8.0_92" 
Java(TM) SE Runtime Environment (build 1.8.0_92-b14) 
Java HotSpot(TM) Client VM (build 25.92-b14, mixed mode) 
+0

您可以尝试在命令行上: java的-d64 -version 如果它不是一个64位版本,你会得到一个消息如下所示: 此Java实例不支持64位JVM。请安装所需的版本。 查阅JVM的帮助选项以获取更多信息java -help – Massimo 2017-07-02 18:31:17