Chúng tôi đang chạy một ứng dụng web nhỏ được viết JRuby trên Rails đang chạy dưới Tomcat. Chúng tôi đang sử dụng back-end Spring được chia sẻ với một ứng dụng web sản xuất khác. Thật không may, chúng tôi tiếp tục gặp vấn đề với PermGen.Theo dõi vấn đề PermGen với JRuby trên Rails trong Tomcat
Hệ điều hành: Ubuntu Linux 2.6.24-24-server # 1 SMP x86_64 GNU/Linux Java: 1.6.0_21 Tomcat: 6.0.28 JRuby: 1.5.0 Rails: 2.3.7
Chúng tôi hiện đang được Google, Yahoo và Baidu thu thập dữ liệu để sử dụng trang web tăng lên. Tôi đã theo dõi Tomcat với JConsole và chúng tôi chắc chắn đang gặp vấn đề với một số lượng quá nhiều lớp học. Khi tomcat khởi chạy, chúng tôi có khoảng 12.000 lớp được tải. Sau 8 giờ, chúng tôi có gần 75.000 lớp được tải. PermGen tăng từ 100MB lên 460MB cùng một lúc.
Việc xếp lớp đang hoạt động nhưng chỉ tải xuống ~ 500 lớp trong cùng khoảng thời gian 8 giờ đó. PermGen dường như không bao giờ được thu thập.
Chúng tôi đang chạy với các tùy chọn VM sau cho Tomcat:
-Xms2048m -Xmx2048m -XX:MaxPermSize=512m -XX:PermSize=128m \
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:ParallelGCThreads=4 \
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
Rõ ràng có một số loại rò rỉ. Câu hỏi đặt ra là ở đâu? Bất kỳ lời khuyên nào về cách theo dõi ai và ai chịu trách nhiệm về điều này? Tôi hy vọng đó là một số sai lầm thực sự ngớ ngẩn về phía chúng tôi, nhưng tôi không chắc chắn nên bắt đầu từ đâu.
Mọi lời khuyên sẽ được đánh giá cao.
EDIT
Dường như chúng ta đang thấy một lớp mới được tạo ra cho mọi yêu cầu đến duy nhất.
EDIT 2
Nó chắc chắn liên quan đến JRuby. Sử dụng JConsole, tôi đã kích hoạt chế độ Verbose cho trình nạp lớp. Đây là mẫu từ catalina.out:
[Loaded anon_class1275113147_895127379 from file:/opt/apache-tomcat-6.0.28/webapps/notes/WEB-INF/lib/jruby-core-1.5.0.jar]
[Loaded anon_class1354333392_895127376 from file:/opt/apache-tomcat-6.0.28/webapps/notes/WEB-INF/lib/jruby-core-1.5.0.jar]
[Loaded anon_class1402528430_895127373 from file:/opt/apache-tomcat-6.0.28/webapps/notes/WEB-INF/lib/jruby-core-1.5.0.jar]
Vì vậy, câu hỏi sẽ trở thành cách tôi theo dõi bên chịu trách nhiệm tạo các lớp bổ sung đó?
EDIT 3
Không chắc nếu điều này vấn đề, nhưng bằng cách nào đó chúng ta kết thúc với một số điên của bộ tải lớp. Ran jmap -permstat PID
và đã nhận:
class_loader classes bytes parent_loader alive? type
total = 1320 135748 947431296 N/A alive=1, dead=1319 N/A
Điều đó có vẻ hơi quá mức. Phần lớn là một trong ba loại trình nạp lớp: sun.reflect.DelegatingClassLoader
, org.jruby.util.JRubyClassLoader
hoặc org.jruby.util.ClassCache$OneShotClassLoader
. Một lần nữa, đầu ra mẫu từ jmap -permstat
:
class_loader classes bytes parent_loader alive? type
0x00007f71f4e93d58 1 3128 0x00007f71f4d54680 dead sun/reflect/[email protected]
0x00007f721e51e2a0 57103 316038936 0x00007f720431c958 dead org/jruby/util/[email protected]
0x00007f72182f2b10 4 12944 0x00007f721d7f3030 dead org/jruby/util/[email protected]
0x00007f721d7d50d8 9 457520 0x00007f720431c958 dead org/jruby/util/[email protected]
75.000 lớp học cho 4 trường hợp vẫn còn có vẻ như rất nhiều với tôi ... :) Nhưng tôi chắc chắn sẽ làm một số thử nghiệm nhiều hơn nữa. Cảm ơn! – organicveggie
Điều liên quan đến tôi là có vẻ như mọi yêu cầu mới tạo ra các lớp mới chưa bao giờ được phát hành. Điều đó không cảm thấy đúng với tôi. Tôi hiểu lý do tại sao JRuby đang tạo ra các lớp học mới, nhưng tôi không thể hiểu tại sao họ không được làm sạch ... – organicveggie
Làm cách nào để biết liệu jruby.compile.mode = OFF có hoạt động chính xác không? Tôi đã thêm -Djruby.compile.mode = OFF vào CATALINA_OPTS trong catalina.sh, bắt đầu tomcat và khởi chạy một webcrawler chống lại trang web. JConsole chỉ ra rằng tổng số lớp và tổng số permgen đang tăng đều đặn. – organicveggie