Không phải là công cụ cụ thể, mà là kỹ thuật gỡ lỗi để theo dõi mã nào chịu trách nhiệm về kết nối mở hoặc tài nguyên khác.
Tôi giả sử bạn đang sử dụng một phương pháp nhất quán ở phía bên java để nhận kết nối db (gộp chung hoặc không quan trọng).
Ý tưởng là tạo lớp bao bọc rất nhẹ xung quanh nhà máy/hồ bơi kết nối của bạn hoặc bất kể nó là gì.Trình bao bọc sẽ thực hiện bất kỳ giao diện jdbc nào có ý nghĩa, do đó bạn có thể trao đổi nó cho đối tượng kết nối bình thường của bạn nhưng hầu hết các phương thức sẽ chỉ gọi/trả về kết nối cơ bản một cách minh bạch.
Nếu bạn đang sử dụng một số loại khung công tác IoC (ví dụ: mùa xuân), bạn sẽ có thể dễ dàng trao đổi lớp kết nối/nhà máy ở cấp cấu hình. Bây giờ tất cả mã java của bạn sẽ sử dụng trình bao bọc kết nối db mới của bạn.
Nếu bạn đang sử dụng một hồ bơi, sau đó gọi connection.close()
thường chỉ trả về đối tượng vào hồ bơi thay vì hủy kết nối. Vì vậy, kỹ thuật này hoạt động cho rò rỉ kết nối bình thường hoặc chỉ là "không trả lại cho hồ bơi (hồ bơi kiệt sức)" rò rỉ.
Bây giờ chúng ta chỉ cần ghi lại các bit thú vị và đặt bẫy cho các kết nối bị rò rỉ.
Stack trace để xác định tác giả
Trong constructor hoặc phương pháp nhà máy cho wrapper kết nối của bạn tạo ra một đối tượng mới Throwable
và lưu nó như là một biến địa phương trong wrapper của bạn cho sau này. Chúng tôi sử dụng Throwable
vì nó nhanh hơn/rẻ hơn sử dụng Thread.currentThread().getStackTrace()
.
Đặt "cái bẫy"
Thực hiện phương pháp finally
trong lớp wrapper của bạn. Đây là phương thức dọn dẹp được gọi bởi GC khi đối tượng đang bị hủy vì nó không còn được sử dụng nữa.
Phương pháp finally
nên kiểm tra "Tôi có đóng cửa không?". Nếu đã đóng, thì mọi thứ đều ổn ... tuy nhiên nếu kết nối đang được GC và nó không bị đóng ... thì đây là kết nối "bị rò rỉ".
Bây giờ, Throwable
sẽ hoạt động trở lại. Chúng ta có thể lấy Throwable
và xuất ra một thông điệp tường trình tốt đẹp nói một cái gì đó như: "Tôi là một kết nối bị rò rỉ và đây là một dấu vết ngăn xếp liên quan đến tác giả của tôi."
Mở rộng ý tưởng
Phương pháp này có thể được điều chỉnh cho nhiều tình huống khác nhau. Tất nhiên, bạn có thể giữ các loại dữ liệu khác trong trình bao bọc của bạn để khắc phục sự cố cụ thể của bạn. Ví dụ thời gian tạo. Sau đó, bạn có thể thăm dò ý kiến cho các kết nối lâu dài và một lần nữa ngụ ý người sáng tạo. Hoặc bạn có thể thăm dò các kết nối hiện có và phân tích các dấu vết ngăn xếp Throwable
để nhận dữ liệu trên mã nào đang sử dụng số lượng kết nối theo thời gian.
Có lẽ một công cụ có sẵn cũng có thể làm những việc này, nhưng số lượng mã cần thiết để áp dụng kỹ thuật này là rất tối thiểu trong hầu hết các trường hợp (giả sử bạn có cách dễ dàng để hoán đổi db kết nối nhà máy mà không cần tìm kiếm thay thế toàn bộ codebase của bạn).
Trong khi P6Spy là một công cụ tốt, tôi không thấy nó giúp với các vấn đề rò rỉ kết nối săn bắn. –