2012-04-25 36 views
6

Tôi bị rò rỉ bộ nhớ trong hai ứng dụng trong máy chủ Tomcat 6.0.35 xuất hiện "không có nơi nào". Một ứng dụng là Solr và ứng dụng kia là phần mềm của riêng chúng tôi. Tôi hy vọng một người nào đó đã thấy điều này trước đây vì nó đã xảy ra với tôi trong vài tuần qua và tôi phải tiếp tục khởi động lại Tomcat trong một môi trường sản xuất.Rò rỉ bộ nhớ trong nhiều ứng dụng

Nó xuất hiện trên máy chủ gốc của chúng tôi mặc dù không có mã nào liên quan đến hoạt động kết nối luồng hoặc kết nối DB đã được chạm vào. Khi máy chủ cũ, ứng dụng này chạy được do đã được gỡ bỏ, tôi đã di chuyển trang web sang máy chủ mới và môi trường "sạch hơn" với ý tưởng sẽ xóa mọi nội dung cũ. Nhưng nó vẫn tiếp tục xảy ra.

Ngay trước khi Tomcat tắt nhật ký catalina.out được làm đầy với các lỗi như:

2012-04-25 21: 46: 00.300 [chính] ERROR org.apache.catalina.loader.WebappClassLoader- Ứng dụng web [/ AppName] dường như đã bắt đầu một chuỗi có tên [MultiThreadedHttpConnectionManager cleanup] nhưng đã không dừng được. Điều này rất có khả năng để tạo ra một rò rỉ bộ nhớ.

2012-04-25 21: 46: 00,339 [chính] ERROR org.apache.catalina.loader.WebappClassLoader- Ứng dụng web [/ AppName] dường như đã bắt đầu một chuỗi có tên [com.mchan ge.v2 .async.ThreadPoolAsynchronousRunner $ PoolThread- # 2] nhưng đã không dừng được. Điều này rất có khả năng để tạo ra một rò rỉ bộ nhớ.

2012-04-25 21: 46: 00,470 [chính] ERROR org.apache.catalina.loader.WebappClassLoader- Ứng dụng web [/ AppName] vẫn đang xử lý yêu cầu chưa đến hạn ish. Điều này rất có khả năng để tạo ra một rò rỉ bộ nhớ. Bạn có thể kiểm soát thời gian được phép đối với các yêu cầu hoàn thành bằng cách sử dụng thuộc tính unloadDelay của việc triển khai Conte xt chuẩn.

Trong quá trình di chuyển đó, chúng tôi đã chuyển từ Solr 1.4-> Solr 3.6 để khắc phục sự cố. Khi các lỗi ở trên bắt đầu điền nhật ký lỗi Solr dưới đây sau ngay sau lặp lại 10-15 lần và sau đó tomcat ngừng hoạt động và tôi phải tắt máy và khởi động để làm cho nó phản hồi.

2012-04-25 21: 46: 00.527 [chính] ERROR org.apache.catalina.loader.WebappClassLoader- Các ứng dụng web [/ Solr] tạo một ThreadLocal với chìa khóa của loại [org.a Pache .solr.schema.DateField.ThreadLocalDateFormat] (giá trị [[email protected]]) và một giá trị kiểu [org.apache.solr. schema.DateField.ISO8601CanonicalDateFormat] (giá trị [[email protected]d43a]) nhưng không thể xóa nó khi trang web đã dừng trang web . Điều này rất có khả năng để tạo ra một rò rỉ bộ nhớ.

Nghiên cứu của tôi đã đưa ra rất nhiều đề xuất về việc thay đổi mã quản lý chuỗi để đảm bảo chúng loại bỏ các kết nối DB gộp lại, nhưng mã này chưa được thay đổi trong gần 12 tháng. Ngoài ra các ứng dụng Solr là crashing và đó là bên thứ 3 vì vậy suy nghĩ của tôi là đây là môi trường (jar xung đột, versioning, cấu hình chất béo fingered?)

Thay đổi cuối cùng của tôi đã cập nhật kết nối mysql cho java mới nhất như một số rò rỉ bộ nhớ các lỗi đã tồn tại xung quanh việc tổng hợp trong các bản phát hành trước đó nhưng máy chủ chỉ bị rơi một lần nữa chỉ sau vài giờ.

Một điều tôi vừa nhận thấy là tôi đang nhìn thấy hàng nghìn phiên trong trình quản lý trang web Tomcat nhưng đó có thể là một cá trích đỏ.

Nếu có ai thấy trợ giúp này được đánh giá rất nhiều.

[Chỉnh sửa]

Tôi nghĩ rằng tôi đã tìm thấy nguồn gốc của vấn đề. Nó không phải là một rò rỉ bộ nhớ sau khi tất cả. Tôi đã thực hiện một ứng dụng từ một nhóm phát triển khác sử dụng c3p0 để nhóm cơ sở dữ liệu qua Hibernate. c3p0 có một lỗi/tính năng mà nếu bạn không phát hành kết nối DB c3p0 có thể đi vào trạng thái chờ khi tất cả các kết nối (thông qua MaxPoolSize: mặc định là 15) được sử dụng. Nó sẽ đợi vô thời hạn để kết nối có sẵn. Do đó gian hàng của tôi.

Tôi đã tăng MaxPoolSize trước tiên từ 25-> 100 và ứng dụng của tôi chạy trong vài ngày mà không bị treo và sau đó từ 100-> 1000 và nó chạy ổn định kể từ (trên 2 tuần). Đây không phải là giải pháp hoàn chỉnh vì tôi cần phải tìm hiểu lý do tại sao nó chạy ra khỏi các kết nối gộp nên tôi cũng đặt unreturnedConnectionTimeout thành 4hrs của c3p0, thực thi giới hạn thời gian 4hr trên tất cả các kết nối bất kể chúng có hoạt động hay không . Nếu đó là một kết nối hoạt động, nó sẽ đóng nó lại và mở lại.

Không đẹp và c3p0 không đề xuất nhưng nó mang lại cho tôi một số không gian thở để tìm ra nguồn gốc của vấn đề.

Lưu ý: khi sử dụng c3p0 với Hibernate, các cài đặt được lưu trữ trong tệp persistence.xml của bạn nhưng không phải tất cả các cài đặt đều có thể được đặt ở đó. Một số thiết lập (ví dụ unreturnedConnectionTimeout) phải đi c3p0.properties

+0

Hãy thử quan sát jvm tomcat bằng jvisualvm trong jdk. –

+0

Cảm ơn Thorbjørn. Tôi để jvisualvm chạy qua đêm và không có gì nổi bật. GC đã xảy ra như mong đợi, nhiều không gian heap (~ 30% sử dụng, tối đa 50% được sử dụng), PermGen là tốt (~ 30% sử dụng). Tôi không có cấu hình JMX để truy cập từ xa nên tôi không có được bức tranh hoàn chỉnh. Tôi tắt jvisualvm để lái xe vào công việc và nhận được một cuộc gọi 30 phút sau để nói rằng trang web đã được phục vụ lên trang đầu nhưng bất kỳ truy cập cơ sở dữ liệu (đăng nhập/tìm kiếm) đã có mặt đất để ngăn chặn một lần nữa. Rất lạ. –

+0

có vẻ là một vấn đề tương tự về mở trên https://rés.apache.org/jira/browse/SOLR-2357 chưa được khắc phục – JoseK

Trả lời

2

Bạn nói rằng chuỗi các sự kiện là:

  • lỗi xuất hiện
  • Tomcat ngừng đáp ứng
  • khởi động lại là cần thiết

Tuy nhiên , các thông báo lỗi rò rỉ bộ nhớ chỉ được báo cáo khi ứng dụng web bị dừng. Vì vậy, một cái gì đó đang kích hoạt các ứng dụng web để dừng lại (hoặc tải lại). Bạn cần phải tìm ra những gì đang kích hoạt này và ngăn chặn nó.

Về rò rỉ thực tế, bạn có thể thấy hữu ích này:

http://people.apache.org/~markt/presentations/2010-11-04-Memory-Leaks-60mins.pdf

Có vẻ cả hai ứng dụng và Solr của bạn có một số rò rỉ mà cần phải được cố định. Bài thuyết trình sẽ cung cấp cho bạn một số gợi ý. Tôi cũng sẽ xem xét nâng cấp lên phiên bản 7.0.x mới nhất. Việc phát hiện rò rỉ bộ nhớ đã được cải thiện và không phải tất cả các cải tiến đã biến nó thành 6.0.x.

+1

Cảm ơn Mark, tôi đã lấy lời khuyên của bạn và chuyển sang TC7 nhưng như bạn đã chỉ ra đúng Tôi đã có xe trước khi ngựa tức làvấn đề chỉ trông giống như nó đã gây ra rò rỉ bộ nhớ nhưng thực chất là kết quả của vấn đề không phải là cách khác. Khi tôi cài đặt TC7, nó có thể không tìm thấy rò rỉ nên tôi bắt đầu nhìn vào các khu vực khác và hóa ra đó là khóa kết nối phân vùng kết nối DB gây ra sự cố như đã nêu ở trên. –

+0

@Mark, Vừa mới xem bản trình bày tuyệt vời của bạn. tôi có một câu hỏi, bạn đang nói tomcat sẽ giúp trong ứng dụng tạo ra rò rỉ (Tomcat có thể thử và xóa ThreadLocal, Tomcat có thể thử và dừng thread). Vì vậy, những gì thời điểm tomcat sẽ chăm sóc này, làm thế nào tomcat quyết định này là không sử dụng và cần được loại bỏ? – Vipin

+0

@Vipin Tomcat sẽ cố gắng khắc phục các sự cố này khi ứng dụng web bị dừng. Tomcat quyết định chúng cần phải được xóa vì chúng đã được tải bởi trình nạp lớp ứng dụng web - tại thời điểm ứng dụng web bị dừng, không nên sử dụng nữa. –