2009-03-26 21 views
5

Đó là một ứng dụng web Java trên Websphere6.1, Solaris 10, JDK 1.5.0_13. Chúng tôi đặt kích thước heap tối đa là 1024m. jmap cho thấy trạng thái heap là lành mạnh. Việc sử dụng bộ nhớ heap chỉ là 57%. Không có OutOfMemory nào cả.Làm thế nào để tiến trình Java với -Xmx1024m chiếm bộ nhớ cư trú 3GB?

Nhưng chúng tôi thấy RSS rất cao (3GB) cho quá trình java này từ ps. pmap hiển thị khối bộ nhớ riêng 1.9G.

 
3785: /dmwdkpmmkg/was/610/java/bin/java -server -Dwas.status.socket=65370 -X 
Address Kbytes  RSS Anon Locked Pgsz Mode Mapped File 
... 
0020A000 2008 2008 2008  - 8K rwx-- [ heap ] 
00400000 1957888 1957888 1957888  - 4M rwx-- [ heap ] 
8D076000  40  40  40  - 8K rw--R [ stack tid=10786 ] 
... 

Đây có phải là lỗ hổng bộ nhớ heap trong mã gốc không? Cách tiếp cận nào được khuyến khích để tìm ra nguyên nhân gốc rễ?

Trả lời

4

Tài liệu Troubleshooting Memory Leaks từ Sun này có thể giúp bạn tìm ra vấn đề tại sao RSS cao của bạn, đặc biệt trong phần 3.4.

Khi bạn đang chạy Websphere, có thể bạn có thể sử dụng -memorycheck trên máy ảo của mình. Để biết chi tiết, hãy xem here.

Nó không nhất thiết phải bị rò rỉ trong mã gốc. Nếu bạn nhìn here, trên Solaris có thể có vấn đề với các tệp đang được mở.

Nó chỉ là một loạt các liên kết và gợi ý, nhưng có thể hữu ích để theo dõi vấn đề của bạn.

+0

Chúng hữu ích. Trong khi -memorycheck dường như chỉ có sẵn cho IBM JDK? Không có IBM JDK trên Solaris, chỉ cần SUN JDK, phải không? – gengmao

+0

Không biết, tôi không có kinh nghiệm với Solaris, nhưng có thể không ... Có lẽ IBM JDK đang đến với Websphere vì nó cũng từ IBM. Đó là những gì tôi nghĩ đến. – MicSim

1

Bạn có đang sử dụng thư viện JNI không? Tôi không chắc làm thế nào mã nguồn gốc phân bổ RAM nhưng đó là nơi tôi muốn bắt đầu tìm kiếm.

2

Kích thước heap theo kích thước heap Java, vẫn còn VM và các thư viện khác là một phần của quy trình.

Hãy thử chạy Hello World với kích thước heap 1024m và "for (;;)" trong đó và xem nó mất bao nhiêu. Điều đó sẽ cung cấp cho bạn một đường cơ sở để sử dụng bộ nhớ tổng thể.

3

Điều này có thể xảy ra ngay cả khi không có rò rỉ bộ nhớ riêng (như tài nguyên zip không được đính kèm).

Tôi đã gặp phải vấn đề tương tự. Đây là vấn đề được biết đến với glibc> = 2.10

Việc chữa bệnh là để thiết lập biến env này export MALLOC_ARENA_MAX=4

bài viết của IBM về việc thiết MALLOC_ARENA_MAX https://www.ibm.com/developerworks/community/blogs/kevgrig/entry/linux_glibc_2_10_rhel_6_malloc_may_show_excessive_virtual_memory_usage?lang=en

Google cho MALLOC_ARENA_MAX hoặc tìm kiếm nó trên SO để tìm rất nhiều tài liệu tham khảo.

Bạn có thể muốn điều chỉnh cũng tùy chọn malloc khác để tối ưu hóa cho phân mảnh thấp của bộ nhớ phân bổ:

# tune glibc memory allocation, optimize for low fragmentation 
# limit the number of arenas 
# requires glibc >= 2.16 since there was a bug in 
# MALLOC_ARENA_TEST parameter handling that cause MALLOC_ARENA_MAX not to work 
export MALLOC_ARENA_MAX=2 
# disable dynamic mmap threshold, see M_MMAP_THRESHOLD in "man mallopt" 
export MALLOC_MMAP_THRESHOLD_=131072 
export MALLOC_TRIM_THRESHOLD_=131072 
export MALLOC_TOP_PAD_=131072 
export MALLOC_MMAP_MAX_=65536 

Bạn có thể gọi hàm malloc_info mẹ đẻ để có được thông tin về cấp phát bộ nhớ. Dưới đây là ví dụ về using JNA to call the native malloc_info method.

+0

Cảm ơn Lari! Câu trả lời của bạn rất thuyết phục. Tuy nhiên tôi không có ứng dụng và solaris env để xác minh nữa - câu hỏi gốc đã được nâng lên 6 năm trước :) Nhưng cảm ơn vì đã cho tôi biết dù sao đi nữa. Câu hỏi đã được tôi bí ẩn trong một thời gian. – gengmao

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