2010-12-30 25 views
53

Câu hỏi này dành cho những ai đã từng thử nghiệm nút "Tìm rò rỉ" trong quản lý Tomcat và có một số kết quả như thế này:Có cách nào để tránh rò rỉ bộ nhớ thất bại trong Tomcat không?

Các ứng dụng web sau đây đã bị chặn lại (nạp lại, undeployed), nhưng lớp học của họ từ trước chạy vẫn được nạp trong bộ nhớ, gây rò rỉ bộ nhớ (sử dụng một hồ sơ để xác nhận):
/rò rỉ-app-tên

tôi giả định này có cái gì để làm với điều đó "không gian Perm Gen" lỗi mà bạn thường gặp phải với việc triển khai lại thường xuyên.

Vì vậy, những gì tôi thấy trong jconsole khi tôi triển khai là các lớp tải của tôi đi từ khoảng 2k đến 5k. Sau đó, bạn sẽ nghĩ rằng một undeployment nên thả chúng xuống 2k nhưng họ vẫn ở 5k.

Tôi cũng đã cố gắng sử dụng các tùy chọn JVM sau:

-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled

tôi đã thấy dips RẤT nhỏ trong khoảng không gian Perm Gen sử dụng nhưng không phải những gì tôi mong đợi và đếm lớp được nạp không rơi vãi.

Vì vậy, có cách nào để định cấu hình Tomcat hoặc thiết kế ứng dụng của bạn để tải lên tốt hơn khi không triển khai? Hoặc chúng ta có bị mắc kẹt khi khởi động lại máy chủ sau một số phiên gỡ lỗi chính không?

Tomcat phiên bản đầu ra:

phiên bản Server: Apache Tomcat/6.0.29
máy chủ được xây dựng: 19 Tháng bảy 2010 1458
số Server: 6.0.0.29
OS Name: Windows 7
OS Phiên bản: 6.1
Kiến trúc: x86
Phiên bản JVM: 1.6.0_18-b07
Nhà cung cấp JVM: Sun Microsystems Inc.

Cập nhật:

Nhờ câu trả lời celias' Tôi quyết định làm một ít đào hơn và tôi nghĩ rằng tôi xác định thủ phạm là trong ứng dụng nhờ tôi để CXF, mùa xuân và JAXB.

Sau khi tôi biết cách cấu hình một ứng dụng Java, tôi đã chỉ ra trình biên dịch tại Tomcat và lấy một số đống và ảnh chụp nhanh để xem các đối tượng và các lớp trông như thế nào trong bộ nhớ. Tôi phát hiện ra rằng một số liệt kê từ lược đồ XML của tôi được sử dụng trong các lớp được tạo ra của tôi CXF/JAXB (wsdl2java) đã được kéo dài sau khi một sự thất nghiệp. Theo bãi chứa đống của tôi, có vẻ như các vật thể được gắn với Bản đồ. Disclaimer: Tôi thừa nhận tôi vẫn còn một chút màu xanh lá cây với hồ sơ và truy tìm cây gọi của một đối tượng có thể được thử thách trong Java.

Ngoài ra tôi nên đề cập đến rằng tôi thậm chí không gọi dịch vụ, chỉ cần triển khai sau đó không triển khai nó. Bản thân các đối tượng dường như được nạp thông qua sự phản chiếu bắt đầu từ Spring khi triển khai. Tôi tin rằng tôi đã theo quy ước để thành lập một dịch vụ CXF vào mùa xuân. Vì vậy, tôi không chắc chắn 100% nếu đây là lỗi Spring/CXF, JAXB hoặc phản chiếu.

Lưu ý phụ: ứng dụng được đề cập là dịch vụ web sử dụng Spring/CXF và XML xảy ra là một lược đồ khá phức tạp (một phần mở rộng của NIEM).

Trả lời

15

Nếu bạn muốn chắc chắn không gây rò rỉ, bạn phải làm như sau:

  • Hãy chắc chắn rằng ứng dụng web của bạn không sử dụng bất kỳ lớp học java mà đang ở trong thư viện chứa web chia sẻ. Nếu bạn có bất kỳ thư viện được chia sẻ nào, hãy đảm bảo rằng không có tham chiếu mạnh nào tới các đối tượng trong các thư viện đó
  • Tránh sử dụng các biến tĩnh, đặc biệt là đối tượng java như HashTable, Sets, v.v. để giải phóng các đối tượng với các bản đồ, danh sách ...

đây cũng là một bài viết tốt về ThreadLocal và MemoryLeaks - http://blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/

+0

thông tin tốt! Tôi đã thử tạo một ứng dụng rất đơn giản mà không cần bất kỳ bên thứ 3 hoặc libs được chia sẻ nào và không thấy các triệu chứng tương tự như tôi đã nêu ở trên. Vấn đề duy nhất là một ứng dụng "thế giới thực" có thể sẽ có một số rò rỉ bộ nhớ ở đâu đó với việc sử dụng libs của bên thứ 3. Vì vậy, tôi đoán nó tất cả đi xuống đến các nhà phát triển một nơi nào đó dọc theo dòng. Tôi chắc rằng tất cả chúng ta có thể cải tiến: Tomcat, Apps, Libraries ... – waltwood

+1

Có ai biết nhiều hơn về hiệu ứng của việc tạo mã byte động vì nó được sử dụng bởi nhiều serializer XML, Hibernate, Tapestry? Các thư viện này có tải đúng cách không? – Codo

+0

Ok, tôi đã vội vàng nói rằng tôi không thấy các triệu chứng tương tự. Có lẽ ứng dụng thử nghiệm của tôi quá nhỏ để chú ý. Tôi đã thử nghiệm với ứng dụng ví dụ Tomcat, và một lần nữa tôi thấy PermGen lấp đầy và các lớp được nạp không bao giờ quay trở lại đường cơ sở sau khi undeployment. Tôi hiểu rằng PermGen được sử dụng để lưu trữ siêu dữ liệu về các lớp được tải. Vì vậy, tôi sẽ nghĩ rằng một undeployment nên Tomcat để giảm tài liệu tham khảo lớp học cho một ứng dụng và GC nên xóa chúng và siêu dữ liệu của họ lên phải không? Ngay cả khi các lớp của tôi có chứa các tham chiếu mạnh mẽ đến các lớp khác, chúng có nên chết khi Tomcat dỡ bỏ các lớp cha mẹ không? – waltwood

6

Tomcat 7 được cho là sẽ mang lại những cải tiến trong lĩnh vực này. Xem Features of Apache Tomcat 7, phần có tiêu đề Không có Rò rỉ nào khác!

Họ tin rằng giờ đây họ có thể đối phó với nhiều rò rỉ bộ nhớ do các ứng dụng web gây ra. Thật không may, nó vẫn còn trong phiên bản beta.

Ngoài ra, tôi chỉ có thể nói rằng tôi đã thực hiện cùng một trải nghiệm và chưa tìm thấy giải pháp. Triển khai thường yêu cầu khởi động lại Tomcat sau đó. Tôi không biết thủ phạm là ai: ứng dụng web của tôi, Tomcat, Hibernate, Tapestry hoặc một vài trong số đó.

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