添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

The code below produces a memory leak.

public static BufferedImage mergeImages2(BufferedImage base, Collection<Light> images) {
    BufferedImage output = new BufferedImage(base.getWidth(), base.getHeight(), BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = output.createGraphics();
    g.drawImage(base, 0, 0, null);
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1.0f));
    for (Light l : images) {
        g.drawImage(l.LIGHT_IMAGE, l.x, l.y, null);
        l.LIGHT_IMAGE.flush();
    g.dispose();
    output.flush();
    return output;

As I have read here: BufferedImage.getGraphics() resulting in memory leak, is there a fix? .createGraphics() is the problem.

This code can be executed quite often (a timer is set up to tick at a constant rate of 50ms and if a light is "moving" it calls this code, but if lights stay in the same place this is skipped). It runs fine but everytime makes the process clunk memory, which is a cascade process eventually leading to an increase from ~180 000 K memory to more than 600 000 K memory in less then one minute. Graphically it works fine until at some point the clunk becomes too much (obviously) and FPS drop drastically.

Now I have narrowed down that this block produces the leak as commenting its call out makes the problem go away.

The base image drawn is 1024x561 and the lights' images are rather small (50x50). I have always been testing it with only one light in the array so far.

Any solutions to avoiding the memory leak?

This is definitely bug in JVM, I've experienced the same issue, the system completely runs out of memory. – Vojtěch Nov 19, 2013 at 8:15

As Andrew Thompson commented, this is not necessarily a memory leak. The garbage collector might simply start later than you think. You could try experimenting with a System.gc() call, when the lights are not moving, although generally calling System.gc() is not recommended: When does System.gc() do anything

Alternatively you could try to manipulate directly the integer arrays that are behind your BufferedImage (not easy), or perhaps to use another API (like JOGL).

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.