2012-06-20 7 views
8

Tôi có một chương trình java thực hiện 5 tác vụ khác nhau. Khi tôi chạy chương trình với tham số bộ nhớ -Xmx512m, nhiệm vụ 1-4 chạy tốt nhưng nhiệm vụ 5 hết bộ nhớ. Khi tôi chạy chương trình với -Xmx1024m, tất cả 5 nhiệm vụ chạy tốt nhưng nhiệm vụ 1-4 mà trước đó chạy tốt với heap 512m hiện nay sử dụng hết gần như tất cả các heap 1024m. Điều tương tự cũng xảy ra nếu tôi sử dụng -Xms128m -Xmx1024m.Làm thế nào để hướng dẫn JVM để giữ chân bộ nhớ càng thấp càng tốt?

Thông số bộ nhớ để hướng dẫn JVM giữ mức sử dụng bộ nhớ thấp (ví dụ: 512m cho nhiệm vụ 1-4) và chỉ sử dụng nhiều bộ nhớ hơn khi thực sự cần thiết (ví dụ: trong trường hợp nhiệm vụ 5)?

Có lẽ tôi cần một cách để kích hoạt bộ thu gom rác thường xuyên hơn cài đặt mặc định?

+0

Bạn phân biệt các tác vụ nào sử dụng dung lượng bộ nhớ như thế nào? – Poindexter

+0

Tại sao có bao nhiêu nhiệm vụ 1-4 sử dụng? Bạn đã phân bổ một gigabyte cho toàn bộ chương trình. –

+0

@Poindexter Tôi chuyển một tham số dòng lệnh để chỉ ra tác vụ nào cần chạy. Sau đó, tôi sử dụng 'prstat' để xem việc sử dụng bộ nhớ của chương trình. – Raihan

Trả lời

5

Tôi nghĩ bạn có hiểu lầm về cách JVM hoạt động. Đây không phải là vấn đề GC hoặc vấn đề "nhiệm vụ".

Nhiệm vụ của bạn bị rò rỉ bộ nhớ hoặc chúng được thiết kế để chứa nhiều bộ nhớ hơn.

-Xmx1024m đặt bộ nhớ tối đa mà JVM có thể cấp phát. Nó sẽ giống như nếu bạn chỉ có bộ nhớ vật lý 1024 megabyte và không có bộ nhớ ảo.

Sẽ hữu ích khi cập nhật câu hỏi của bạn với định nghĩa Nhiệm vụ. Có phải 5 JVM riêng biệt này không? Hoặc chỉ 5 đơn vị công việc trong một JVM đơn lẻ.

Cập nhật

Tôi không có ý định chương trình để sử dụng tất cả đống 1g luôn. Ý định của tôi là hướng dẫn JVM sử dụng heap 512m nếu có thể quản lý và sử dụng nhiều bộ nhớ hơn nếu cần. Khi bộ nhớ không còn cần thiết, để giảm trở lại 512m hoặc thậm chí ít hơn số lượng bộ nhớ.

Chỉ vì bạn đặt -Xmx1024m không có nghĩa là JVM S use sử dụng tất cả bộ nhớ đó. Nó chỉ là giới hạn tối đa. Đặt Xms cho đến khi đặt số lượng bộ nhớ tối thiểu được sử dụng. Chương trình của bạn cuối cùng sẽ xác định số lượng bộ nhớ đang chạy được sử dụng. Nếu nó đạt đến giới hạn được thiết lập bởi -Xmx thì nó sẽ ném một OutOfMemoryError

Bạn có thể đề xuất với JVM để chạy Bộ thu gom rác bằng cách gọi System.gc(). Chú ý tôi đã đề nghị, bạn không thể ép buộc GC chạy. Bạn có thể chạy trên một nền tảng từ chối thậm chí làm GC. Bạn cũng cần phải xem xét những gì thuật toán GC nó được lựa chọn cho ứng dụng của bạn. Tôi sẽ xem xét ở đây Tuning Garbage Collector.

Nếu bạn cần các điều khiển hạt mịn như vậy đối với việc sử dụng bộ nhớ, bạn sẽ cần phải chọn một thứ khác ngoài JVM.

+0

Khi tôi chạy chương trình, tôi chuyển một tham số dòng lệnh cho biết trong số 5 nhiệm vụ mà chương trình thực hiện. Trong suốt thời gian tồn tại của chương trình, trong khi chạy tác vụ được yêu cầu, tôi theo dõi việc sử dụng bộ nhớ của chương trình. Trong trường hợp nhiệm vụ 1-4, khi tôi sử dụng -Xmx512m, tôi quan sát việc sử dụng bộ nhớ tăng lên khoảng 512m trước khi hoàn thành. Khi tôi sử dụng -Xmx1024m, việc sử dụng bộ nhớ tăng lên khoảng 1024m trước khi hoàn thành khi nó có thể chỉ sử dụng 512m. – Raihan

+0

@Raihan Có hai điều tôi có thể nghĩ về điều này. Bạn đang tìm kiếm bộ nhớ không được hoán đổi. Hoặc GC không chạy mạnh mẽ khi bạn cung cấp cho nó nhiều bộ nhớ hơn vì vậy nó đang định giá hiệu suất sử dụng bộ nhớ. Nếu nó nhận ra nó sắp hết bộ nhớ, nó sẽ cố gắng giải phóng càng nhiều tài liệu tham khảo. Nếu nó có nhiều bộ nhớ, nó có thể để chúng một mình. –

+0

@Raihan Nếu bạn phải gắn bó với JVM, hãy tìm số lượng bộ nhớ tối đa bạn cần chạy trong mọi trường hợp. Sau đó đề xuất cho hệ thống GC với System.gc(). Trong trường hợp -Xmx1024m của bạn, hãy gọi System.gc() và sau đó xem liệu mức sử dụng của bạn có cao hơn không. Cũng nên ghi nhớ để đọc các giá trị bộ nhớ chính xác. Chỉ vì JVM deallocated tất cả các bộ nhớ không có nghĩa là hệ điều hành sẵn sàng lấy tất cả bộ nhớ ra khỏi quá trình chỉ được nêu ra. –

1

Bằng cách truyền -Xmx1024m đến máy ảo thứ bạn về cơ bản cho máy ảo biết rằng nó có thể sử dụng tối đa 1 gig đống, mà cuối cùng nó sẽ làm. VM bắt đầu chạy bộ sưu tập rác khi cần, ví dụ. khi heap trở nên được sử dụng hết, phụ thuộc vào kích thước heap có sẵn. Nếu bạn biết nhiệm vụ nào chạy bên ngoài (mà tôi đoán bạn làm vì bạn chuyển nó thành tham số dòng cmd), tại sao không đặt -Xmx từ bên ngoài?

+0

Có cách nào đề nghị bộ thu gom rác không đợi cho đến khi tất cả số lượng -Xmx đống được sử dụng hết trước khi bắt đầu, thay vào đó để bắt đầu bất cứ khi nào một số bộ nhớ mới 'X' được cấp phát? – Raihan

+0

Có một loạt các cờ bạn có thể chơi xung quanh với: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html Tôi không chắc chắn về tác động của một số cờ có mặc dù. – jayeff

8

Hai thông số đề nghị các JVM khi nó cần phải điều chỉnh kích thước heap của nó:

-XX:MaxHeapFreeRatio=10 
-XX:MinHeapFreeRatio=10 

mà khá nhiều có nghĩa là nếu sau khi gc, hơn 10% của heap là miễn phí, nó sẽ cố gắng để cung cấp cho bộ nhớ trở lại hệ điều hành. và nó sẽ phát triển heap chỉ khi hơn 90% đống được sử dụng sau gc.

điều này có thể làm chậm chương trình của bạn, vì gc sẽ liên tục thay đổi kích thước bộ nhớ được phân bổ. và có thể nó sẽ không có tác dụng gì cả nếu chương trình của bạn phân bổ lượng bộ nhớ lớn trong một khoảng thời gian ngắn.