2013-05-28 31 views
8

Cố gắng gỡ lỗi máy ảo Java không đúng. Quá trình được đề cập là một VM lớn (100GB heap) chạy Sun VM 1.6u24 trên Centos 5 đang thực hiện công việc back-end thông thường - tức là truy cập cơ sở dữ liệu, tệp I/O và vv.JVM định kỳ treo

Sau khi quá trình được khởi động lại để nâng cấp phiên bản phần mềm, chúng tôi nhận thấy rằng thông lượng của nó đã giảm đáng kể. Hầu hết thời gian, báo cáo hàng đầu quá trình Java hoàn toàn sử dụng 2 lõi. Trong thời gian đó, VM hoàn toàn không chịu trách nhiệm: không có nhật ký nào được viết và nó không phản hồi các công cụ bên ngoài như jstack hoặc kill -3. Một khi VM phục hồi, quá trình này tiếp tục như bình thường, cho đến khi treo tiếp theo.

strace cho thấy rằng trong quá trình treo, chỉ có 2 chuỗi tạo cuộc gọi hệ thống. Đây là các chủ đề VM "VM Thread" (21776) và "VM Periodic Task Thread" (21786). Có lẽ, 2 luồng này đang sử dụng hết thời gian CPU. Các chủ đề ứng dụng thỉnh thoảng thức dậy và làm công việc của họ. Phần còn lại của thời gian dường như họ đang chờ đợi nhiều futexes khác nhau. Ngẫu nhiên, dòng đầu tiên của pha bình thường luôn là SIGSEGV.

[pid 21776] sched_yield()    = 0 
[pid 21776] sched_yield()    = 0 
[pid 21776] sched_yield(<unfinished ...> 
[pid 21786] <... futex resumed>)  = -1 ETIMEDOUT (Connection timed out) 
[pid 21776] <... sched_yield resumed>) = 0 
[pid 21786] futex(0x2aabac71ef28, FUTEX_WAKE_PRIVATE, 1 <unfinished ...> 
[pid 21776] sched_yield(<unfinished ...> 
[pid 21786] <... futex resumed>)  = 0 
[pid 21786] clock_gettime(CLOCK_MONOTONIC, {517080, 280918033}) = 0 
[pid 21786] clock_gettime(CLOCK_REALTIME, {1369750039, 794028000}) = 0 
[pid 21786] futex(0x2aabb81b94c4, FUTEX_WAIT_PRIVATE, 1, {0, 49923000} <unfinished ...> 
[pid 21776] <... sched_yield resumed>) = 0 
[pid 21776] sched_yield()    = 0 
[pid 21776] sched_yield()    = 0 
[pid 21955] --- SIGSEGV (Segmentation fault) @ 0 (0) --- 
[pid 21955] rt_sigreturn(0x2b1cde2f54ad <unfinished ...> 

Sự cố hiển thị trong 2 máy chủ khác nhau. Quay trở lại phiên bản mã của chúng tôi chỉ làm việc cho một trong 2 máy chủ. Không có thông báo lỗi nào được báo cáo trong nhật ký hệ thống và một quá trình Java khác trên máy bị ảnh hưởng hoạt động chính xác.

đầu ra sau này được thu thập với gstack và cho thấy 2 điển hình xử lí ứng dụng chờ đợi:

Thread 552 (Thread 0x4935f940 (LWP 21906)): 
#0 0x00000030b040ae00 in [email protected]@GLIBC_2.3.2() from /lib64/libpthread.so.0 
#1 0x00002b1cdd8548d6 in os::PlatformEvent::park(long)() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#2 0x00002b1cdd92b230 in ObjectMonitor::wait(long, bool, Thread*)() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#3 0x00002b1cdd928853 in ObjectSynchronizer::wait(Handle, long, Thread*)() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#4 0x00002b1cdd69b716 in JVM_MonitorWait() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#5 0x00002b1cde193cc8 in ??() 
#6 0x00002b1ce2552d90 in ??() 
#7 0x00002b1cdd84fc23 in os::javaTimeMillis()() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#8 0x00002b1cde188a82 in ??() 
#9 0x0000000000000000 in ??() 
Thread 551 (Thread 0x49460940 (LWP 21907)): 
#0 0x00000030b040ab99 in [email protected]@GLIBC_2.3.2() from /lib64/libpthread.so.0 
#1 0x00002b1cdd854d6f in Parker::park(bool, long)() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#2 0x00002b1cdd98a1c8 in Unsafe_Park() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#3 0x00002b1cde193cc8 in ??() 
#4 0x000000004945f798 in ??() 
#5 0x00002b1cde188a82 in ??() 
#6 0x0000000000000000 in ??() 

Chúng tôi đã xem xét vấn đề với ntpd, trong đó có bước nhảy vọt lỗi thứ hai, nhưng cách giải quyết đề nghị không giúp đỡ, không phải đã sử dụng máy chủ NTPD bên ngoài. Khởi động lại chính máy cũng không giúp ích gì. Chúng tôi đã bật tính năng ghi nhật ký GC và không phải là vấn đề về GC vì không có thông báo nào cho biết. Tìm kiếm bất kỳ đề xuất nào có thể giúp với vấn đề này, bất kỳ trợ giúp nào cũng được đánh giá cao.

+1

Có thể là "tạm dừng GC" không? bạn đã kiểm tra thuật toán GC đang được sử dụng chưa? http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html#0.0.0.%20The%20Concurrent%20Low%20Pause%20Collector%7Coutline – kosa

+0

Tôi đồng ý với @Nambari - Tôi đã đã thấy tạm dừng rất dài trong các JVM lớn khi chúng đang được tải. Nếu quá trình GC không thể hoàn thành trong một khoảng thời gian hợp lý, bạn có thể gặp lỗi Out of Memory. JVM của bạn thực sự cần phải lớn như vậy? –

+0

Vùng heap càng lớn, càng nhiều đối tượng cần phải được giải quyết bằng quy trình GC –

Trả lời

3

Dưới đây là một vài điều tôi muốn xem xét:

  • Khi JVM là không đáp ứng, sử dụng iostatvmstat để xem nếu hệ thống là sân đập. Điều này có thể xảy ra khi bạn cấp phát bộ nhớ quá mức; tức là hệ thống tổng thể của bạn đang sử dụng bộ nhớ ảo nhiều hơn đáng kể so với bộ nhớ vật lý.

  • Bật ghi nhật ký GC của JVM và xem liệu có sự tương quan giữa JVM không hoạt động và GC không.