2009-04-30 84 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