2009-06-12 31 views
23

Kích thước heap tối đa mà bạn có thể phân bổ trên Windows 32 bit cho một quy trình Java bằng cách sử dụng -Xmx là gì?Dung lượng bộ nhớ tối đa cho mỗi quá trình Java trên Windows?

Tôi hỏi vì tôi muốn sử dụng dữ liệu ETOPO1 trong OpenMap và tệp float nhị phân thô là khoảng 910   MB.

+1

Có vẻ giống như một bản sao của http://stackoverflow.com/questions/171205/java-maximum-memory-on-windows-xp. –

+2

Tôi nên ngừng đếm trên tìm kiếm người hỏi câu hỏi. –

Trả lời

44

Không có gì tốt hơn thử nghiệm thực nghiệm để trả lời câu hỏi của bạn. Tôi đã viết một chương trình Java và chạy nó trong khi chỉ định cờ XMX (cũng được sử dụng XMS = XMX để buộc JVM phân bổ trước tất cả bộ nhớ). Để bảo vệ hơn nữa chống lại các tối ưu hóa JVM, tôi đã chủ động phân bổ số lượng X đối tượng 10MB. Tôi chạy một số thử nghiệm trên một số JVM tăng giá trị XMX cùng với việc tăng số lượng MB được phân bổ, trên một hệ điều hành 32 bit khác nhau sử dụng cả Sun và IBM JVM, dưới đây là tóm tắt kết quả:

OS : Windows XP SP2, JVM: Sun 1.6.0_02, Kích thước tối đa heap: 1470 MB
Hệ điều hành: Windows XP SP2, JVM: IBM 1.5, Kích thước heap tối đa: 1810 MB
Hệ điều hành: Windows Server 2003 SE, JVM: IBM 1.5 , Kích thước heap tối đa: 1850 MB
Hệ điều hành: Linux 2.6, JVM: IBM 1.5, Kích thước heap tối đa: 2750 MB

Dưới đây là các nỗ lực chạy chi tiết cùng với nguồn cấp hỗ trợ cấp phối hợp tác de:

WinXP SP2, SUN JVM:

 
C:>java -version 
java version "1.6.0_02" 
Java(TM) SE Runtime Environment (build 1.6.0_02-b06) 
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode)

java -Xms1470m -Xmx1470m Class1 142 ... about to create object 141 object 141 created

C:>java -Xms1480m -Xmx1480m Class1 145 Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.

WinXP SP2, IBM JVM
 
C:>c:\ibm\jdk\bin\java.exe -version 
java version "1.5.0" 
Java(TM) 2 Runtime Environment, Standard Edition (build pwi32devifx-20070323 (if 
ix 117674: SR4 + 116644 + 114941 + 116110 + 114881)) 
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32 j9vmwi3223ifx-2007 
0323 (JIT enabled) 
J9VM - 20070322_12058_lHdSMR 
JIT - 20070109_1805ifx3_r8 
GC - WASIFIX_2007) 
JCL - 20070131

c:\ibm\jdk\bin\java.exe -Xms1810m -Xmx1810m Class1 178 ... about to create object 177 object 177 created

C:>c:\ibm\jdk\bin\java.exe -Xms1820m -Xmx1820m Class1 179 JVMJ9VM015W Initialization error for library j9gc23(2): Failed to instantiate he ap. 1820M requested Could not create the Java virtual machine.

Win2003 SE, IBM JVM
 
C:>"C:\IBM\java" -Xms1850m -Xmx1850m Class1 
sleeping for 5 seconds. 
Done.

C:>"C:\IBM\java" -Xms1880m -Xmx1880m Class1 JVMJ9VM015W Initialization error for library j9gc23(2): Failed to instantiate he ap. 1880M requested Could not create the Java virtual machine.

Linux 2.6, IBM JVM
 
[[email protected] ~]# /opt/ibm/java2-i386-50/bin/java -version 
java version "1.5.0" 
Java(TM) 2 Runtime Environment, Standard Edition (build pxi32dev-20060511 (SR2)) 
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20060504 (JIT enabled) 
J9VM - 20060501_06428_lHdSMR 
JIT - 20060428_1800_r8 
GC - 20060501_AA) 
JCL - 20060511a

/opt/ibm/java2-i386-50/bin/java -Xms2750m -Xmx2750m Class1 270

[[email protected] ~]# /opt/ibm/java2-i386-50/bin/java -Xms2800m -Xmx2800m Class1 270 JVMJ9VM015W Initialization error for library j9gc23(2): Failed to instantiate heap. 2800M requested Could not create the Java virtual machine.

Dưới đây là các mã:


import java.util.StringTokenizer; 


public class Class1 { 

     public Class1() {} 

     private class BigObject { 
       byte _myArr[]; 
       public BigObject() { 
         _myArr = new byte[10000000]; 
       } 
     } 
    public static void main(String[] args) { 
       (new Class1()).perform(Integer.parseInt(args[0])); 
     } 
     public void perform(int numOfObjects) { 
       System.out.println("creating 10 MB arrays."); 
       BigObject arr[] = new BigObject[numOfObjects]; 
       for (int i=0;i <numOfObjects; i++) { 
         System.out.println("about to create object "+i); 
         arr[i] = new BigObject(); 
         System.out.println("object "+i+" created"); 
       } 
       System.out.println("sleeping for 5 seconds."); 
       try { 
       Thread.sleep(5000); 
       }catch (Exception e) {e.printStackTrace();} 
       System.out.println("Done."); 
    } 

} 
+0

Tôi giả định rằng bạn có số lượng bộ nhớ tối đa cho hệ điều hành 32 bit cho thử nghiệm này. –

+1

Chính xác những gì bạn đã nói. Đối với bản cập nhật Windows 7 64 bit và Sun JDK 6 27 bit, kích thước heap tối đa là 1220 MB; mặc dù máy tính có RAM 6 GB. –

2

Như đã nêu trong câu hỏi được đề cập trong nhận xét, có giới hạn thực tế, khoảng 1200   MB.

Tuy nhiên, tình huống bạn mô tả có chiều sâu hơn so với kích thước bộ nhớ tuyệt đối.

Khi bạn đọc dữ liệu nhị phân 910   MB và xây dựng một đối tượng mạng khỏi nó (trái ngược với việc duy trì dữ liệu dưới dạng mảng byte), bạn sẽ tiêu thụ nhiều bộ nhớ hơn 910   MB. Một ước tính hợp lý sẽ là biểu diễn trong bộ nhớ sẽ tiêu thụ gấp đôi bộ nhớ nhiều - đó là vì (1) mỗi đối tượng chứa một con trỏ bổ sung (đối với lớp của đối tượng); và (2) có rất nhiều dữ liệu sổ kế toán. Ví dụ nếu bạn sử dụng một HashMap để quản lý các đối tượng của bạn thì ngoài mỗi đối tượng bạn cũng phân bổ một đối tượng Map.Entry có thể dễ dàng tiêu thụ 16 hoặc 20 byte (phụ thuộc thực hiện).

Mặt khác, vẫn còn hy vọng: bạn có thực sự cần duy trì tất cả 910   MB trong bộ nhớ không? Bạn không thể chỉ xây dựng một cái gì đó mà đọc dữ liệu một cách lười biếng? Kết hợp với WeakReferences tôi nghĩ bạn có thể rút nó ra.

+0

Trên thực tế, nó được lưu trữ như một mảng lớn của phao. –

-2

Trên Windows 32 bit, theo mặc định, mọi ứng dụng đều có thể sử dụng tối đa 2   GB không gian địa chỉ ảo. Tôi đoán điều này làm cho -Xmx2048M. Tuy nhiên, nếu bạn đã cài đặt thêm RAM, bạn có thể tăng không gian địa chỉ ảo lên tới 3   GB bằng cách sử dụng các tham số thời gian khởi động.

Trong boot.ini, bạn có thể tạo ra một tùy chọn khởi động mới như thế này:

[boot loader]<br> 
timeout=5<br> 
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS<br> 
[operating systems]<br> 
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional - magyar" /noexecute=optin /fastdetect /usepmtimer<br> 
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional - magyar 3GB" /noexecute=optin /fastdetect /usepmtimer /3GB /USERVA=2800<br> 

đây bằng cách điều chỉnh/USERVA = 2800 tham số, bạn có thể điều chỉnh máy tính của bạn. Nhưng lưu ý rằng một số cấu hình không thích các giá trị cao trong tham số này - mong đợi sự cố.

+1

Bạn thực sự không thể phân bổ tất cả điều đó đến đống trong một tiến trình Java. Tôi đã phân bổ thành công nhất là 1400M, và đó chỉ là một hộp duy nhất - tôi không thể tái tạo thành công ở bất kỳ nơi nào khác! –

+0

Tôi đã phân bổ thành công 1500M trên Vista. Tôi đã không thử bất kỳ giữa đó và 1600M nhưng 1600M không hoạt động. –

+0

Bây giờ tôi cũng đã thử nó. Trên máy tính của tôi với 2GB ram và 1400MB miễn phí, JVM chỉ chạy khi tôi chỉ định -Xmx1400M hoặc nếu không nó sẽ cung cấp lỗi "Không thể dự trữ đủ dung lượng cho đối tượng heap". – akarnokd

4

Đối với một tập tin lớn tôi đề nghị bạn sử dụng một bộ nhớ ánh xạ tập tin. Điều này không sử dụng không gian heap (hoặc rất ít) vì vậy kích thước heap tối đa không phải là một vấn đề trong trường hợp này.

+0

Thú vị. Bạn có một liên kết tốt cho kỹ thuật này? –

3

Gần đây, chúng tôi đã chuyển từ Windows sang Linux (do các vấn đề về kích thước VM).

Tôi đã nghe nói về nhiều con số được ném xung quanh trong quá khứ cho kích thước máy ảo Windows (1200, 1400, 1600, 1800). Trên Máy chủ Windows (2003), trong môi trường của chúng tôi, với các ứng dụng của chúng tôi, ... Tôi chưa bao giờ sử dụng thành công hơn 1280MB. Ngoài ra, ứng dụng của chúng tôi bắt đầu trưng bày các vấn đề về GC và OOM.

Mỗi khi tôi nhận được phiên bản VM mới, tôi đã thử thay đổi số và nó không bao giờ thay đổi.

Bạn có tệp 900MB ngay bây giờ, nếu tệp tăng lên 1300MB thì sao? Bạn sẽ làm gì?

Bạn có một số tùy chọn

  1. Cảng sang Linux/Solaris. Điều này chỉ cần phần cứng/phần mềm và thường là một bài tập chuyển đổi đơn giản.
  2. Sử dụng Windows 64 bit. Điều này có thể không được miễn phí các vấn đề GC mặc dù - Tôi đã nghe nói về những câu chuyện khác nhau với vbit 64bit.
  3. Thiết kế lại ứng dụng để xử lý tệp khác nhau, Bạn có thể chia tệp một cách hợp lý theo cách nào đó, bạn có thể đọc tệp theo khối và xử lý tệp khác theo cách khác không?

Những người khác sử dụng OpenMap phải gặp sự cố này. Bạn có thể khai thác kiến ​​thức của mình và không phát minh lại bất kỳ bánh xe nào không?

+0

Tôi đã đi cho một nhu cầu ngắn hạn để làm cho một loại bản demo của điều. Nó chắc chắn sẽ tốt hơn khi chỉ đọc phần mà tôi cần và làm giảm hiển thị từ ETOPO1 xuống còn 5 hoặc 10 tùy thuộc vào mức thu phóng. –

Các vấn đề liên quan