2015-09-30 13 views
9

Và nói chung, là các đơn vị được sử dụng cho các tùy chọn -Xmx, -Xms-Xmn ("k", "M" và "G" hoặc ít khả năng tiêu chuẩn "K", "m" hoặc "g") Binary prefix bội số (tức là quyền hạn của 1024), hoặc là họ quyền hạn của 1000?Có phải java -Xmx1G có nghĩa là 10^9 hoặc 2^30 byte không?

Sách hướng dẫn cho biết chúng đại diện cho kilobyte (kB), megabyte (MB) và gigabyte (GB), cho thấy chúng có công suất 1000 như được xác định trong hệ thống SI gốc. Các bài kiểm tra không chính thức của tôi (rằng tôi không tự tin lắm) đề nghị họ thực sự là kibibytes (kiB), mebibytes (MiB)gibibytes (GiB), tất cả quyền hạn của 1024.

Vậy điều gì là đúng? Ví dụ. mã Java nào sẽ hiển thị kích thước hiện tại?

Sử dụng bội số của 1024 không có gì đáng ngạc nhiên đối với kích thước bộ nhớ RAM, vì RAM thường được đặt vật lý bằng cách tăng gấp đôi các mô-đun phần cứng. Nhưng việc sử dụng các đơn vị một cách rõ ràng và tiêu chuẩn là quan trọng hơn bao giờ hết khi chúng ta nhận được các quyền hạn lớn hơn và lớn hơn, vì tiềm năng cho sự nhầm lẫn phát triển. Đơn vị "t" cũng được JVM của tôi chấp nhận và 1 TiB lớn hơn 10 TB so với 1 TB. Lưu ý: nếu đây thực sự là bội số nhị phân, tôi đề nghị cập nhật tài liệu và giao diện người dùng rất rõ ràng về điều đó, với các ví dụ như "Nối chữ k hoặc K để chỉ kibibyte (1024 bytes), hoặc m hoặc M để biểu thị các mebibyte (1048576 byte) ". Đó là cách tiếp cận được thực hiện, ví dụ: trong Ubuntu: UnitsPolicy - Ubuntu Wiki.

Lưu ý: để biết thêm về các tùy chọn được sử dụng cho, xem ví dụ: java - What are the Xms and Xmx parameters when starting JVMs?.

+0

@ElliottFrisch Chủ yếu tôi đang đặt câu hỏi, tìm câu trả lời dứt khoát. Đề xuất tài liệu chỉ nhằm mục đích thêm rõ ràng hơn về những gì tôi đang bối rối. – nealmcb

Trả lời

17

Câu trả lời ngắn: Tất cả các kích cỡ bộ nhớ được sử dụng bởi các đối số dòng lệnh JVM được quy định trong các đơn vị nhị phân truyền thống, nơi một kilobyte là 1024 byte, và những người khác đang gia tăng quyền hạn của 1024.

Long trả lời:

This documentation page on the command line arguments nói những điều sau đây áp dụng cho tất cả các đối số chấp nhận kích thước bộ nhớ:

Ví dụ, để thiết lập kích thước tới 8 GB, bạn có thể chỉ định một trong hai 8g, 8192m, 8388608k hoặc 8589934592 làm đối số.

Đối -Xmx, nó mang lại cho những ví dụ cụ thể:

Các ví dụ sau đây cho thấy làm thế nào để thiết lập tối đa cho phép kích thước của bộ nhớ phân bổ cho 80 MB sử dụng các đơn vị khác nhau:

-Xmx83886080
-Xmx81920k
-Xmx80m

Trước khi tôi nghĩ để kiểm tra tài liệu (tôi giả sử bạn đã có?), Tôi đã kiểm tra nguồn của HotSpot và tìm thấy các giá trị bộ nhớ được phân tích cú pháp trong src/share/vm/runtime/arguments.cpp theo hàm atomull (có vẻ như là "ASCII to memory, unsigned lâu dài "):

// Parses a memory size specification string. 
static bool atomull(const char *s, julong* result) { 
    julong n = 0; 
    int args_read = sscanf(s, JULONG_FORMAT, &n); 
    if (args_read != 1) { 
    return false; 
    } 
    while (*s != '\0' && isdigit(*s)) { 
    s++; 
    } 
    // 4705540: illegal if more characters are found after the first non-digit 
    if (strlen(s) > 1) { 
    return false; 
    } 
    switch (*s) { 
    case 'T': case 't': 
     *result = n * G * K; 
     // Check for overflow. 
     if (*result/((julong)G * K) != n) return false; 
     return true; 
    case 'G': case 'g': 
     *result = n * G; 
     if (*result/G != n) return false; 
     return true; 
    case 'M': case 'm': 
     *result = n * M; 
     if (*result/M != n) return false; 
     return true; 
    case 'K': case 'k': 
     *result = n * K; 
     if (*result/K != n) return false; 
     return true; 
    case '\0': 
     *result = n; 
     return true; 
    default: 
     return false; 
    } 
} 

những hằng K, M, G được định nghĩa trong src/share/vm/utilities/globalDefinitions.hpp:

const size_t K     = 1024; 
const size_t M     = K*K; 
const size_t G     = M*K; 

Tất cả điều này khẳng định tài liệu, ngoại trừ hỗ trợ mà cho hậu tố T cho terabyte dường như được thêm vào sau và hoàn toàn không được ghi lại.

Không bắt buộc phải sử dụng hệ số đơn vị, vì vậy nếu bạn muốn một tỷ byte bạn có thể viết -Xmx1000000000. Nếu bạn sử dụng một số nhân, chúng là nhị phân, do đó, -Xmx1G có nghĩa là 2 byte hoặc một thanh RAM '.

(Điều này không thực sự đáng ngạc nhiên, bởi vì Java có trước nỗ lực của IEC để xác định lại các từ hiện có trước đó. lần thỉnh thoảng ý nghĩa của chúng là không rõ ràng. Ví dụ, gigabyte nhị phân (GB) = 1024 byte, và gigabyte thập phân (GB) = 1000 byte. Nhưng không, họ định nghĩa lại những từ mà mọi người đã sử dụng, không tránh khỏi sự nhầm lẫn bùng nổ và chúng tôi bị mắc kẹt với những điều khoản chú hề "gibibyte", "tebibyte" và phần còn lại. Chúa ơi, hãy tha thứ cho chúng tôi.)

+2

Cảm ơn bạn đã tìm mã ! Rất rõ ràng. Nhưng tôi phải lưu ý rằng đó là những người máy tính đã xác định lại các thuật ngữ rõ ràng trước đây đã hơn hai thế kỷ. Đối với IEC để giữ chúng như chúng đã được sử dụng quá lâu, và cung cấp các điều khoản mới cho các đơn vị mới, làm cho tất cả các loại ý nghĩa với tôi. MiB kém cồng kềnh hơn và dễ định dạng hơn, được dịch, v.v. hơn "megabyte nhị phân" hoặc "MB_2". – nealmcb

+0

Cảm ơn bạn đã tìm tài liệu đó. Nó có nhiều ví dụ rõ ràng hơn để làm rõ việc sử dụng MB và GB so với tài liệu tôi đã tìm thấy trên hệ thống của mình (Ubuntu) và trong các tìm kiếm trên web của tôi. Có vẻ như họ đã làm rõ nó, có lẽ cho Java 8 :) – nealmcb

2

Bạn có hai tùy chọn để nhận câu trả lời cho câu hỏi của mình:

a) kiểm tra mã nguồn của JDK. Xin lỗi tôi đã không thể google nó trong 5 phút.

b) viết mô phỏng, chạy mô phỏng nhiều lần và thực hiện một số quan sát.

public class A { 
    public static void main(String[] args) throws Exception { 
    System.out.println("total: " + Runtime.getRuntime().totalMemory()); 
    } 
} 

Và chạy nó nhiều lần:

đoán
java -Xms130m -Xmx2G A 
total: 131072000 
java -Xms131m -Xmx2G A 
total: 132644864 
java -Xms132m -Xmx2G A 
total: 132644864 
java -Xms133m -Xmx2G A 
total: 134742016 
java -Xms134m -Xmx2G A 
total: 134742016 

Vì vậy, giáo dục là java không sử dụng một con số chính xác, nhưng 2^n xấp xỉ của số mà bạn yêu cầu.

1

Trong một số khác question liên quan đến cờ -Xmx, Runtime.getRuntime().maxMemory() được sử dụng để hiển thị kích thước hiện tại. Nó cũng lưu ý rằng -Xmx1024m-Xmx1g dẫn đến kết quả giống hệt nhau, cho biết rằng các số này là lũy thừa của hai chứ không phải là mười.

Lưu ý sự khác biệt giữa totalMemory()maxMemory().
What are Runtime.getRuntime().totalMemory() and freeMemory()?

+0

Câu hỏi mà bạn tham khảo là tại chỗ! Kiểm tra cụ thể [class MemTest by Alex] (http: // stackoverflow.com/a/23702224/507544) ở đó, để có kế toán đầy đủ về bộ nhớ không phải bộ nhớ heap (bao gồm bộ nhớ Cache Code, và nhóm gen Perm) so với bộ nhớ heap (bao gồm cả không gian Eden, không gian Survivor và các nhóm gen đã có) – nealmcb

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