Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  When to call Graphics.dispose()  (Read 6173 times)
0 Members and 1 Guest are viewing this topic.
Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Posted 2003-07-07 11:12:00 »

How do you know when you are supposed to call dispose() on a Graphics object?  I've seen code in examples, even in Sun's tutorials, where I've expected that dispose() should be called but it isn't.   In the same way I've seen code call dispose() when I didn't think it was needed.

E.g. in your paint(Graphics g) method you would typically not call dispose on the Graphics passed in, right?
But if you get the Graphics object for a buffered image you should call dispose() when you are done drawing to it, right?

Can somebody clarify exactly when it is needed, and when it isn't? And what harm it might do to call it when not needed, or not call it when needed.

Offline kevglass

JGO Kernel


Medals: 186
Projects: 24
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #1 - Posted 2003-07-07 11:25:18 »

Just guessing here, but you should only call dispose() on a graphics context that you have ownership of?

In the case of paint(Graphics g):

You were passed the graphics context from the infrastructure around you. It will clear up whatever needs clearing up. Its not right for you to dispose() it, its not yours two dispose. Not to mention, it might be passed to someone else subsequently and you disposing it might screw things up.

In the case of getGraphics() from BufferedImge:

You own the graphics context. You know when its finished being used. You can therefore choose when is the correct moment to dispose() it. That said, once you have called dispose(), don't attempt to use it again Wink

Like I said, I don't know for sure.. but ownership would seem to be the key.

Kev

EDIT: not sure this helps any, maybe it only clarifies the question? (I hope)

Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #2 - Posted 2003-07-07 11:59:11 »

Yes.. that is exactly what I assumed.  However I have seen cases of calls to getGraphics() or createGraphics() not matched with a dispose() and was wondering if that was a bug, a leak of some sort, or if there were cases when it simply wasn't needed.

For instance when createGraphics is called on a off-screen BufferedImage, perhaps there are no resources that need disposing, which is different from the case of getting the graphics context for a on-screen component.  In the BufferedImage case I would figure it is still correct to call dispose(), but maybe it doesn't actually do much?

For example look at http://developer.java.sun.com/developer/JDCTechTips/2002/tt0618.html#tip2
createGraphics() is called on BufferedImages with no call to Graphics.dispose().

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Abuse

JGO Knight


Medals: 13


falling into the abyss of reality


« Reply #3 - Posted 2003-07-07 13:49:56 »

yeah, its another grey area that probably needs some refining from Sun.

Calling dispose() on Graphics objects obtained from bufferStrategy.getDrawGraphics() BEFORE calling bufferStrategy.show() is probably a good idea. Grin

The rest probably don't make much of a difference... probably Wink

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline tortoise

Junior Duke




<3 Shmups


« Reply #4 - Posted 2003-07-08 11:29:01 »

I've never noticed any difference in speed, resource use, smoothness, etc when I do or don't call dispose(). I've never been convinced it's a mission critical method call. Although I usually do call it after grabbing and using my own Graphics from BufferStrategy.getDrawGraphics() or BufferedImage.createGraphics().

And doesn't not knowing if you should or should not call a public method on an object kinda go against the whole OO paradigm? If an object gets passed to you that has functionality that you definitely should not invoke, then that functionality shouldn't be public.
Offline Abuse

JGO Knight


Medals: 13


falling into the abyss of reality


« Reply #5 - Posted 2003-07-08 11:58:40 »

Quote

And doesn't not knowing if you should or should not call a public method on an object kinda go against the whole OO paradigm? If an object gets passed to you that has functionality that you definitely should not invoke, then that functionality shouldn't be public.


Thats a very good point!

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #6 - Posted 2003-07-08 13:01:03 »

To be fair it would be difficult to solve the problem of having the object providing the Graphics manage the dispose() stuff on its own.

Obviously dispose() should be called in some cases or it would not have been exposed.  I just wish those cases were documented.

For what it's worth, I've never called dispose() on a Dialog or Frame and apparently you are supposed to do that too.  I guess the native window structures live in memory as long as you haven't disposed? (I assume there is a finalizer on the Window object to handle this as well?  I suppose I could check myself.. but I'm feeling lazy Tongue)

Offline Abuse

JGO Knight


Medals: 13


falling into the abyss of reality


« Reply #7 - Posted 2003-07-08 14:23:04 »

I never called dispose() on any AWT stuff either!

*Until* I started using fullscreen.... now I use it all the time.

In my experience System.exit() causes serious problems when in fullscreen &| using bufferstrategy :-/
(fullscreen often doesn't return the resolution, and bufferstrategy sometimes doesn't de-allocate vram thats its taken for back buffers - hence the app. will mess up after 10-20 runs)

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline trembovetski

Senior Duke




If only I knew what I'm talking about!


« Reply #8 - Posted 2003-07-10 22:32:45 »

Calling Graphics.dispose() is desireable, but not required (which is a pity). After a graphics object is disposed, any rendering to it will be a no-op. You won't leak any resources if you don't, though.

You're supposed to call dispose only for the objects you've created yourself.

It is a good idea to call Window/Frame.dispose() when you're done with the object, because otherwise your app will hang forever (unless you call System.exit explicitly), because AWT Toolkit thread will be running until all windows are disposed of.
Offline Abuse

JGO Knight


Medals: 13


falling into the abyss of reality


« Reply #9 - Posted 2003-07-10 22:53:16 »

Slightly related to this topic.

If you create a JDialog or JWindow using the null parent Constructor; a shared hidden anonymous Frame is created to act as the parent.

However, i've yet to find a way of disposing of this Frame. (Hence can't get the AWT Thread to terminate)

The offending code can be found in SwingUtilities.java Line 1615.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
    static Frame getSharedOwnerFrame() throws HeadlessException {
        Frame sharedOwnerFrame =
            (Frame)SwingUtilities.appContextGet(sharedOwnerFrameKey);
        if (sharedOwnerFrame == null) {
            sharedOwnerFrame = new Frame() {
                public void show() {
                    // This frame can never be shown
                }
                public synchronized void dispose() {
                    try {
                        getToolkit().getSystemEventQueue();
                        super.dispose();
                    } catch (Exception e) {
                        // untrusted code not allowed to dispose
                    }
                }
            };
            SwingUtilities.appContextPut(sharedOwnerFrameKey,
                                         sharedOwnerFrame);
        }
        return sharedOwnerFrame;
    }


Is there a way of disposing of this Frame once it has been created?

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #10 - Posted 2003-07-10 23:47:14 »

Quote
It is a good idea to call Window/Frame.dispose() when you're done with the object, because otherwise your app will hang forever...


Thanks Trembovetski, I knew you would have the answers Smiley.

Does the above statement apply to JDialogs?  And if I don't call dispose on my JDialog will it at least 'dispose' via a finalizer so the AWT thread can die (assuming the finalizer gets a chance to run)?

I wonder if dispose() is not required and you won't leak resources if you don't call it.. what exactly does it do?  It sounds like this is a place were platform specific problems could show up.  I.e. are JRE implementers allowed to make objects leak resources if dispose is not called?

Offline Mark Thornton

Senior Duke





« Reply #11 - Posted 2003-07-11 06:57:55 »

Until you call dispose on a Frame the operating system is considered to have a reference to the Frame which prevents it being collected. In 1.4 and later this also prevents the program from exiting unless the brute force System.exit method is used.
There are also likely to be system resource leaks, but on NT this won't be noticeable (unlike Windows 9X where certain system resources really are limited). Any Graphics object which has an underlying system HDC or equivalent should be disposed (by you if you created it or by the libraries in the case of paint methods). Again Windows NT can tolerate leaking a large number of device contexts but Windows 9X can not.
There are probably no system resources involved in the Graphics created from a BufferedImage, so the dispose is likely to be an empty method. You should still call it and leave the JIT to eliminate the redundant call.

So the rule is simple: call dispose on all Graphics objects which you create and leave the JIT to eliminate the calls which are in fact redundant.
Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #12 - Posted 2003-07-11 10:30:29 »

Yeah, that appears to be the right thing to do.  Now someone tell Sun to update their examples and tutorials so they don't encourage people to ignore dispose()  Smiley

Offline trembovetski

Senior Duke




If only I knew what I'm talking about!


« Reply #13 - Posted 2003-07-11 13:01:55 »

In our current implementation the Graphics object (at least, in Sun's jdk) doesn't hold any native resources, it's a lightweight object which just basically represents current rendering state/attributes.

The native resoucres are associated with the destination surface (component on the screen, or an image). Graphics object has a link to the surface it's associated with, so, for example, if you hold on to the graphics, but let go of the image, the latter won't be collected.  One of the things Graphics.dispose does is it nulls out the link.
It also makes sure that any further rendering to this graphics object are no-ops.

By disposing of the graphics when you're done you're closing the door on stuff like rendering to an obsolete graphics object (even though we handle that for you), or any multithreading issues which may arise (Graphics is not thread-safe), if other thread renders to the graphics object you think you're done with.

As for Window.dispose (and any of it's descendants, basically any toplevel components), Mark nailed it.
Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #14 - Posted 2003-07-11 15:11:59 »

Ah, ok, so the finalizer can't call dispose because the whole point is that the object still lives via the reference the native code is holding.   I have some leaks to patch.... Smiley

Offline leknor

Junior Duke




ROCK!!!


« Reply #15 - Posted 2003-07-12 05:16:55 »

If you feel motivated, please flush out: http://wiki.java.net/bin/view/Games/HowToCallGraphicsDispose with the concise knowledge of this thread.

... and if you hunger for more, give: http://wiki.java.net/bin/view/Games/WebHome some love.
Offline trembovetski

Senior Duke




If only I knew what I'm talking about!


« Reply #16 - Posted 2003-07-18 02:55:25 »

BTW, it's generally not a good idea to use finalizers to dispose of resourses. It takes two full gc cycles to get rid of an object with a finalizer: one to put it into an old gen, and another one to run finalizer and get rid of the object.

I'd suggest using Weak/PhantomReferences with ReferenceQueues instead.

Our gc usage pattern improved a lot once we stopped using finalizers.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (49 views)
2014-10-17 03:59:02

Norakomi (38 views)
2014-10-16 15:22:06

Norakomi (31 views)
2014-10-16 15:20:20

lcass (34 views)
2014-10-15 16:18:58

TehJavaDev (65 views)
2014-10-14 00:39:48

TehJavaDev (65 views)
2014-10-14 00:35:47

TehJavaDev (54 views)
2014-10-14 00:32:37

BurntPizza (72 views)
2014-10-11 23:24:42

BurntPizza (43 views)
2014-10-11 23:10:45

BurntPizza (84 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!