2012-06-19 29 views
8

Tôi có ứng dụng web tomcat trên VPS và đôi khi tomcat (khoảng mỗi tháng một lần)) treo với các lỗi sau trong catalina.out:Tôi nhận được cảnh báo "Java HotSpot (TM) 64-Bit Server VM: Ngoại lệ java.lang.OutOfMemoryError đã xảy ra khi gửi tín hiệu SIGTERM đến handler" lỗi trong tomcat

Java HotSpot (TM) 64-Bit server VM cảnh báo: Exception java.lang.OutOfMemoryError xảy ra dispatching tín hiệu SIGTERM để handler- VM có thể cần phải được chấm dứt cưỡng chế .

Dưới đây là một số chi tiết về cấu hình của tôi:

  • VPS: debian-5.0-x86_64

  • RAM: 2,5 gb,

  • bộ vi xử lý ảo: 8

  • HDD: 60gb hdd - 70% miễn phí

  • Tomcat 7.0

  • java -version:

    java version "1.6.0_18" 
    OpenJDK Runtime Environment (IcedTea6 1.8.13) (6b18-1.8.13-0+squeeze1) 
    OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode) 
    
  • Java params: -Xms512m -Xmx1024m

Tôi có cũng Apache-PHP trên máy chủ đó.

Tôi đang theo dõi tải máy chủ với Munin và nó cho tôi thấy rằng việc sử dụng bộ nhớ và CPU luôn ổn định và không có bất kỳ sự gia tăng nào trước khi gặp sự cố.

Tôi cũng đang ghi nhật ký sử dụng bộ nhớ java qua lớp java.lang.Runtime, và nó cho thấy jvm luôn sử dụng bộ nhớ max200Mb và không có sự gia tăng trước khi gặp sự cố. Nhật ký cuối cùng trước khi xảy ra vụ tai nạn là 40 giây trước và thời gian sử dụng bộ nhớ là: 152Mb.

Ứng dụng web của tôi cũng chạy 6-7 chủ đề thu thập dữ liệu từ các API công cộng khác nhau. Những chủ đề này bắt đầu khi tomcat bắt đầu, và chúng luôn chạy với giấc ngủ định kỳ.

Bạn có thể vui lòng cho tôi biết lý do khiến sự cố xảy ra không? Làm thế nào tôi có thể tìm ra lý do?

Trả lời

0
  • Run top từ vỏ và xem có bao nhiêu bộ nhớ Linux tuyên bố quá trình Java là chiếm.

  • Kiểm tra mức sử dụng bộ nhớ tổng thể trong máy. Có thể là các quá trình khác đang tiêu thụ hết bộ nhớ, buộc Linux phải giết JVM: Một cơ sở dữ liệu như Mysql hoặc Postgress có thể là một nghi ngờ.

  • Kiểm tra /var/log/messages trong khoảng thời gian xung quanh sự cố cho sự kiện bất thường.

0

Bạn có thể chỉnh sửa dịch vụ.bat hoặc dịch vụ.tập tin sh (tìm thấy trong thư mục bin của deistribution) và đặt dưới hai tham số JVM

XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<PATH_TO_WRITE_DUMP> 

Các PATH_TO_WRITE_DUMP nên có quyền cần thiết, Khi bạn nhận được các tập tin dump đống mà sẽ được tạo ra trong trường hợp của một vấn đề OutOfMemory, phân tích nó bằng tay hoặc bằng một số công cụ của bên thứ ba. Bạn có thể tải tệp này trong jvisualvm và thực hiện một số phân tích hoặc bạn có thể sử dụng Memory-Analyzer-Plugin của nhật thực, nó rất hữu ích và cung cấp cho một số nghi ngờ rò rỉ bộ nhớ tiềm năng và cây thống trị (tức là đối tượng thống trị vùng heap) điểm khởi đầu tốt.

0

tăng bạn tomcat bộ nhớ java khởi động, như: bộ JAVA_OPTS = -server -Xms256m -Xmx512m

0

Cho phép tháo đường may này:

Exception java.lang.OutOfMemoryError xảy ra dispatching tín hiệu SIGTERM để handler- VM có thể cần phải được buộc phải chấm dứt.

Trước hết, có vẻ như một thứ gì đó đã gửi JVM (Tomcat) xử lý tín hiệu SIGTERM. Nó phải là một cái gì đó bên ngoài để JVM đã làm điều đó. Một JVM không gửi tín hiệu đến chính nó .

Vì vậy, bạn cần phải tìm ra điều đang làm. Đoán đoán đầu tiên của tôi sẽ là kẻ giết người OOM ... nhưng kẻ giết người OOM sử dụng SIGKILL không SIGTERM. Và JVM không bao giờ thấy SIGKILL sắp tới!

(Bạn có thể xác nhận rằng nó không phải là kẻ giết người oom bằng cách nhìn vào "/ var/log/messages" ... hay bất cứ nơi nào hệ thống các bản ghi thông điệp hạt nhân của mình. Xem How to Configure the Linux Out-of-Memory Killer)

Nếu nó không phải là oom kẻ giết người, sau đó có một vài cách để tìm kiếm nguồn gốc của một tín hiệu:

Và một khi bạn có nguồn gốc của tín hiệu, bạn sẽ có manh mối là tại sao nó đã được gửi.


Điều đáng chú ý khác là OutOfMemoryError xảy ra khi xử lý SIGTERM. Điều này cho thấy rõ ràng (với tôi) rằng nguyên nhân gốc rễ là một cái gì đó đã phát hiện ra rằng Tomcat đang sử dụng quá nhiều bộ nhớ, và đã gửi nó một SIGTERM để làm cho nó biến mất (sạch). Tôi phỏng đoán rằng những gì xảy ra sau đó là JVM đi đến hệ điều hành để yêu cầu bộ nhớ nhiều hơn một chút (để xử lý SIGTERM) và hệ điều hành nói "Không", và JVM ném một số OutOfMemoryError. Thật không may, JVM hiện tại đang ở trạng thái không thể thoát hoặc khôi phục. Do đó nó nói "VM có thể cần phải được buộc phải chấm dứt".


Nhưng dù sao đi nữa. Điều này nhìn tôi như một biểu hiện khá bất thường của một vấn đề Java thông thường. Bạn rất có thể có một lỗi trong các ứng dụng web đang chạy trong Tomcat của bạn đang rò rỉ bộ nhớ. Nếu đúng như vậy, giải pháp thực sự duy nhất là tìm và sửa lỗi. (Tăng kích thước heap ... nếu có thể ... chỉ đặt vấn đề ra. Nó có thể làm giảm khoảng cách giữa các sự cố, nhưng nó không có khả năng ngăn chặn chúng.)

Giả sử rằng bạn đã sẵn sàng để cắn đạn:


1 - Trừ khi có điều gì đó làm điều gì đó hấp dẫn trong mã nguồn gốc ...

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