Tôi đang gặp sự cố với một số phương thức gọi API BufferedImage.getGraphics() của khung API và do đó gây ra rò rỉ bộ nhớ. Phương thức này thực hiện là nó luôn gọi BufferedImage.createGraphics(). Trên máy tính windows, createGraphics() được xử lý bởi Win32GraphicsEnvironment giữ một danh sách nghe bên trong trường của nó displayChanger. Khi tôi gọi getGraphics trên tôi BufferedImage someChart, someChart 's SurfaceManager (mà vẫn giữ được một tham chiếu đến someChart) sẽ được thêm vào nghe bản đồ trong Win32GraphicsEnvironment, ngăn ngừa someChart để được thu gom rác. Không có mục nào sau đó xóa Trình quản lý bề mặt của một sốChủ số từ trình nghe người nghe.BufferedImage.getGraphics() dẫn đến rò rỉ bộ nhớ, có khắc phục không?
Nói chung, con đường tóm tắt dừng một BufferedImage khỏi bị thu gom rác thải, một khi getGraphics được gọi, là như sau:
GC gốc -> localGraphicsEnvironment (Win32GraphicsEnvironment) -> displayChanger (SunDisplayChanger) -> người nghe (bản đồ) ->chính (D3DChachingSurfaceManager) -> bImg (BufferedImage)
tôi có thể đã thay đổi mã của khuôn khổ để sau mỗi lần gọi đến BufferedImage.getGraphics(), tôi giữ một tham chiếu đến SurfaceManager của BufferedImage. Sau đó, tôi nhận được giữ localGraphicsEnvironment, đúc nó vào Win32GraphicsEnvironment, sau đó gọi removeDisplayChangedListener() bằng cách sử dụng tham chiếu đến SurfaceManager của BufferedImage. Nhưng tôi không nghĩ đây là một cách thích hợp để giải quyết vấn đề.
Ai đó có thể giúp tôi với vấn đề này? Cảm ơn rất nhiều!
THÊM CHI TIẾT VÀ KẾT QUẢ
Thành phần Tôi đang cố gắng để thêm vào giao diện người dùng của tôi là làm cho các cuộc gọi đến BufferedImage.getGraphics() mỗi khi nó được sơn lại. Do đó, số lượng rác được giữ bởi displayChanger (bên trong SunGraphicsEnvironment) sẽ phát triển khi thành phần được sơn lại.
Tuy nhiên, mọi thứ một hành xử thật là thú vị đủ:
khi tôi tính hành động của tôi trên giao diện người dùng của tôi mà chắc chắn sẽ kích hoạt thông sơn lại, sau đó kiểm tra số lượng người nghe rác bên displayChanger chống lại đếm của tôi, họ không phù hợp lên. (ví dụ: Có 8 người nghe trước khi nhấp chuột của tôi và tôi đã thực hiện 60 lần nhấp. Sau tất cả, chỉ có 18 người nghe.)
Mặt khác, nếu tôi bật điểm ngắt và bước vào quá trình thêm mọi thứ đến displayListeners, mỗi nhấp chuột duy nhất dẫn đến một mục nhập mới trong displayListeners. Và do đó, mọi BufferedImage được giữ bởi displayListeners trở thành rác.
Tôi coi khả năng SurfaceManager, được sử dụng làm khóa cho displayListeners, có thể được chia sẻ hoặc sử dụng lại, nhưng thử nghiệm của tôi loại trừ khả năng này. Tôi cũng được coi là bộ nhớ đệm và tôi cố ý ngăn chặn bộ nhớ đệm xảy ra bằng cách thực hiện mọi cuộc gọi để sơn lại độc đáo.Tuy nhiên, tôi không biết làm thế nào điều này có thể xảy ra và làm thế nào để giải quyết sự rò rỉ.
Tôi đã thử nhưng không hoạt động. – Huinan