Chúng tôi đã có một sự cố ngừng hoạt động lớn trong ngày hôm nay trong sản xuất, nơi bộ nhớ đã biến mất rất nhanh chóng từ máy chủ web của chúng tôi. Điều này đã được truy trở lại một cơ chế bộ nhớ đệm trong Ninject (tôi nghĩ rằng đó là Activation Cache hoặc một cái gì đó - không hoàn toàn chắc chắn). Sau khi điều tra vấn đề chúng tôi đi đến kết luận rằng chúng tôi đã có một tham chiếu vòng tròn trong phạm vi gọi lại của chúng tôi.rò rỉ bộ nhớ ninject do tham chiếu callback phạm vi tròn
class View
{
Presenter presenter;
View()
{
//service locators are smelly, but webforms forces this uglyness
this.presenter = ServiceLocator.Get<Func<View, Presenter>>()(this);
this.presenter.InitUI();
}
}
class Presenter
{
CookieContainer cookieContainer;
View view;
Presenter(View view, CookieContainer cookieContainer)
{
this.view = view;
this.cookieContainer = cookieContainer;
}
}
class CookieContainer
{
HttpRequest request;
HttpResponse response;
CookieContainer()
{
this.request = HttpRequest.Current.Request;
this.response = HttpRequest.Current.Response;
}
}
Bind<Func<View, Presenter>>().ToMethod(ctx => view =>
ctx.Kernel.Get<Presenter>(new ConstructorArgument("view", view)));
Bind<Presenter>().ToSelf().InTransientScope();
Bind<CookieContainer>().ToSelf().InRequestScope();
Đây là đại diện cho mã của chúng tôi đã gây ra sự cố. Dường như những gì đã xảy ra là phạm vi gọi lại cho CookieContainer là HttpContext.Current, và HttpContext.Current cũng đang được tham chiếu bởi CookieContainer. Vì vậy Ninject không bao giờ có thể cắt xén các cá thể CookieContainer từ bộ nhớ cache của nó, như các cá thể CookieContainer, nơi giữ các đối tượng gọi lại phạm vi của chúng còn sống. Khi chúng ta thay đổi phạm vi của CookieContainer thành thoáng qua, tất cả đều hoạt động tốt, như chúng ta mong đợi. Nhưng tôi vẫn không hoàn toàn chắc chắn tại sao điều này xảy ra vì nó có vẻ như đây là một điều khá thông thường để làm đúng? Có lẽ không phải là ...
Tôi cũng bối rối vì tôi nghĩ rằng nếu đối tượng gọi lại vẫn còn sống như nó đã làm, thì không nên Ninject chỉ cần quay trở lại cùng một thể hiện từ bộ nhớ cache, nhìn như thể gọi lại vẫn còn còn sống, do đó, các trường hợp nên xuất hiện để được trong phạm vi? Tại sao ninject tiếp tục nhận được các phiên bản mới của CookieContainer và lưu chúng vào bộ đệm? Tôi đoán sẽ có những vấn đề khác liên quan đến đối tượng không chính xác quay trở lại, nhưng điều đó sẽ ít nhất chỉ là một lỗi, không phải là một rò rỉ bộ nhớ.
Câu hỏi của tôi là a) chúng tôi đã chẩn đoán lỗi này chính xác chưa? b) có cách tiếp cận được khuyến nghị để thực hiện điều này không xảy ra lần nữa không? c) Tôi có thể đặt một sửa chữa vào mã để kiểm tra loại phụ thuộc vòng tròn này (giả sử chúng tôi đã chẩn đoán chính xác điều này)?
Các bạn đã lưu ass của tôi hôm nay. Chúng tôi đã có chính xác cùng một vấn đề! – pkolodziej