2012-02-21 31 views
10

Câu hỏi về cơ bản có trong tiêu đề.JVM có bắt buộc thu gom rác khi đạt đến giới hạn -Xmx không?

Giả sử bạn có ứng dụng đã đạt đến giới hạn JVM -Xmx. Khi ứng dụng đó đòi hỏi nhiều bộ nhớ hơn thì việc thu gom rác có bắt buộc không? (trong HotSpot JVM)

Điều kỳ lạ thứ hai tôi không thể giải thích là hiện tại tôi có một máy chủ ứng dụng chạy với -Xmx = 2048m, lệnh "trên cùng" (trên linux) báo cáo 2.7g cho quá trình.

Vậy ứng dụng được phép vượt quá -Xmx như thế nào?

Xin cảm ơn,

+1

'-Xmx = 2048' là 2048 byte. Tôi giả sử bạn có nghĩa là '-Xmx = 2048m' Lưu ý: Bạn có thể viết chỉ' -mx2g' là điều tương tự. –

+0

@PeterLawrey Cảm ơn, vâng tôi có nghĩa là 2048m. Đã chỉnh sửa câu hỏi. – Simeon

Trả lời

11

Thực tế GC bình thường được kích hoạt khi thế hệ trẻ đầy (không phải toàn bộ đống) và GC chính được kích hoạt khi không còn khoảng trống trong không gian sống sót, vì vậy một số đối tượng cần được di chuyển sang thế hệ cũ.

+2

+1: Thông thường một không gian được thuê đầy đủ là những gì kích hoạt một GC đầy đủ. Các bộ sưu tập nhỏ thường tránh không gian sống sót được lấp đầy bằng cách di chuyển các vật thể vào không gian đã thuê trước khi điều này xảy ra. –

+2

'-Xmx' chỉ đặt kích thước heap tối đa. Đây thường là khu vực lớn nhất, nhưng không phải là khu vực duy nhất. Bạn có ngăn xếp chuỗi, bộ nhớ trực tiếp, thư viện được chia sẻ, bản thân JVM, v.v. –

1

Có, nếu bạn vẫn không tìm thấy bộ nhớ, nó sẽ tăng lỗi OutOfmemory. Tôi hiểu nó như thế này

3

Đây thường là trường hợp, mặc dù GC thường được kích hoạt sớm hơn nhiều, tùy thuộc vào Bộ thu rác mà bạn sử dụng.

1

IIRC đảm bảo rằng toàn bộ GC sẽ được thực hiện trước khi OutOfMemoryError bị ném. Vì vượt quá giới hạn kích thước heap phải dẫn đến lỗi như vậy, điều đó có nghĩa là bạn sẽ luôn có ít nhất một lần chạy GC đầy đủ khi đạt đến giới hạn.

3

Có, JVM chắc chắn sẽ gọi GC nếu đạt đến giới hạn heap (và có thể sớm hơn nhiều). Nếu cách này không hiệu quả, nó sẽ ném OutOfMemoryError s.

Lý do tại sao bạn đang thấy mức tiêu thụ bộ nhớ quá lớn hơn là tùy chọn -Xmx chỉ giới hạn vùng lưu trữ Java (nơi các đối tượng Java được cấp phát). Có một số vùng bộ nhớ khác được JVM sử dụng thêm: khoảng trống cho ngăn xếp Chủ đề, "PermGen" (nơi các lớp và mã của chúng được lưu trữ), bộ nhớ "trực tiếp" được cấp phát qua ByteBuffers, bộ nhớ được phân bổ bởi thư viện gốc, v.v. các vùng bộ nhớ bổ sung này tồn tại các tùy chọn cấu hình khác cho phép giới hạn chúng, ví dụ -Xss, nhưng một số thậm chí còn nằm ngoài tầm kiểm soát của JVM.

0

Thu gom rác là một khu vực khá lớn, nhưng những gì bạn nói là đúng cho bộ sưu tập đầy đủ (có nhiều loại khác)

Một điều cần phải nhận thức được rằng -Xmx đặt kích thước heap tối đa nhưng cũng có một -Xms, đó là kích thước heap minumum. Ứng dụng của bạn có thể chỉ bắt đầu với cấu hình tối thiểu. Sau đó, nếu bộ nhớ được sử dụng đạt đến đó, nó sẽ kích hoạt một bộ sưu tập rác đầy đủ và tăng số lượng heap có sẵn, từ mức tối thiểu (-Xmx) lên đến một số giá trị nhỏ hơn hoặc bằng mức tối đa (-Xmx). Điều này có thể xảy ra nhiều lần, cho đến khi đạt đến mức tối đa. Sau đó, nó không thể tăng heap nữa nhưng bộ sưu tập rác sẽ tiếp tục xảy ra khi đạt tới mức tối đa đó.

7

Tham số Xmx chỉ xác định kích thước của vùng heap. Quá trình Java mất nhiều bộ nhớ hơn vì heap chỉ là một phần của quá trình Java, tôi đoán bạn cũng có những thứ khác mà quá trình java chứa như thư viện gốc, gen perm và phân bổ bộ nhớ riêng do ứng dụng tạo ra.

Dưới đây là một bài viết tốt đẹp mô tả cấp phát bộ nhớ: http://www.ibm.com/developerworks/java/library/j-nativememory-linux/

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