BufferedImage.getGraphics () приводящий к утечке памяти, является там фиксацией?

У меня есть проблема с некоторой платформой API, называя BufferedImage.getGraphics () методом и таким образом вызывая утечку памяти. То, что делает этот метод, - то, что он всегда называет BufferedImage.createGraphics (). На машине окон, createGraphics () обрабатывается Win32GraphicsEnvironment, который сохраняет список слушателей в его поле displayChanger. То, когда я называю getGraphics на своем BufferedImage someChart, SurfaceManager someChart (который сохраняет ссылку на someChart), добавляется к карте слушателей в Win32GraphicsEnvironment, предотвращая someChart, чтобы быть собранным "мусор". Ничто впоследствии не удаляет SurfaceManager someChart из карты слушателей.

В целом итоговый путь, мешающий BufferedImage быть собранным "мусор", однажды getGraphics, называют, следующие:

Корень GC-> localGraphicsEnvironment (Win32GraphicsEnvironment)-> displayChanger (SunDisplayChanger)-> слушатели (Карта)-> ключ (D3DChachingSurfaceManager)-> bImg (BufferedImage)

Я, возможно, изменил код платформы так, чтобы после каждого названного к BufferedImage.getGraphics (), я сохранил ссылку на SurfaceManager BufferedImage. Затем я овладеваю localGraphicsEnvironment, бросаю его к Win32GraphicsEnvironment, затем называю removeDisplayChangedListener () использованием ссылки на SurfaceManager BufferedImage. Но я не думаю, что это - надлежащий способ решить проблему.

Кто-то мог помочь мне с этой проблемой?Большое спасибо!


БОЛЬШЕ ДЕТАЛЕЙ И РЕЗУЛЬТАТОВ

Компонент, который я пытаюсь добавить к своему UI, выполняет вызовы к BufferedImage.getGraphics () каждый раз, когда он перекрашен. В результате количество мусора, сохраненного displayChangerSunGraphicsEnvironment), должно вырасти, поскольку компонент перекрашен.

Однако вещи поведение достаточно странно:

когда я считал свои действия с моим UI, который, конечно, инициирует перекрашивание, затем проверить число слушателей мусора внутри displayChanger против моего количества, они не совпадают. (например, перед моими щелчками было 8 слушателей, и я сделал 60 щелчков. В конце концов, существует только 18 слушателей.)

С другой стороны, если я включаю точку останова и шаг в процесс добавляющих вещей к displayListeners, каждый щелчок привел к новой записи в displayListeners. И таким образом, каждый BufferedImage, сохраненный displayListeners, становится мусором.

Я рассмотрел возможность SurfaceManager, который используется в качестве ключа для displayListeners, может быть совместно использован или снова использован, все же мой эксперимент исключил эту возможность. Я также рассмотрел кэширование, и я сознательно предотвратил кэширование путем совершения каждого вызова для перекрашивания уникальный. Однако, у меня нет подсказки, как это могло произойти и как решить утечку.

6
задан Huinan 6 June 2010 в 15:43
поделиться

2 ответа

После рендеринга BufferedImage вы должны вызвать dispose () в графическом контексте, возвращаемом createGraphics () . Вот пример и список похожих методов.

Приложение: Это похоже на утечку объекта под названием packratting ; несоответствие слушателя звучит как артефакт использования отладчика. Некоторые идеи можно почерпнуть из статьи Брайана Гетца Устранение утечек памяти с помощью мягких ссылок .

7
ответ дан 16 December 2019 в 21:34
поделиться

Попробуйте вызвать flush () , когда вам больше не нужно изображение.

1
ответ дан 16 December 2019 в 21:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: