Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / February 2007

Tip: Looking for answers? Try searching our database.

forcing finalize()

Thread view: 
cy - 10 Feb 2007 12:31 GMT
I found way to force finalize() using deprecated since JDK 1.1 method:

--------------------------------------------------------------------------
class WebBank {
    boolean loggedIn = false;
    WebBank(boolean logStatus) {
        loggedIn = logStatus;
    }
    void logOut() {
        loggedIn = false;
    }
    protected void finalize() {
        if(loggedIn)
            System.out.println("Error: still logged in");
        // Normally, you'll also call the base-class version:
        // super.finalize();
    }
}
public class BankTest {
    public static void main(String[] args) {
        WebBank bank1 = new WebBank(true);
        WebBank bank2 = new WebBank(true);
        new WebBank(true);
        // Proper cleanup: log out of bank1 before going home:
        bank1.logOut();
        // Forget to logout of bank2 and unnamed new bank
        // Attempts to finalize any missed banks:
        System.out.println("Try 1: ");
        System.runFinalization();
        System.out.println("Try 2: ");
        Runtime.getRuntime().runFinalization();
        System.out.println("Try 3: ");
        System.gc();
        System.out.println("Try 4: ");
        System.runFinalizersOnExit(true);
    }
}
------------------------------------------------------------------
output:
Try 1:
Try 2:
Try 3:
Try 4:
Error: still logged in
Error: still logged in
-------------------------------
only deprecated runFinalizersOnExit() method worked!
why not the others? even System.gc()?
any other non-deprecated way to force finalization?
Greg
Chris Uppal - 10 Feb 2007 16:13 GMT
> I found way to force finalize() using deprecated since JDK 1.1 method:

It's deprecated, and for good reason -- don't use it.

If you want to ensure cleanup on exit then there is a framework for that: see
Runtime.addShutdownHook().

You'd create a list somewhere of the "things" that needed to be cleaned up, and
your shutdown hook would loop over that list doing <something> to each "thing".
If you want earlier cleanup either explicitly, or via finalisation, then the
you explicitly /remove/ the corresponding "thing" from the list as you clean
them up.

Or so I'm told -- I have never once needed to use this feature myself.

   -- chris
Robert Klemme - 10 Feb 2007 16:22 GMT
> only deprecated runFinalizersOnExit() method worked!
> why not the others? even System.gc()?
> any other non-deprecated way to force finalization?

Finalization is not guaranteed.  You cannot rely on it to happen.  Even
if you could there is the issue of making an instance reachable in the
finalizer which will not result in a second invocation of the finalizer
once the object becomes collectible again.

Also, I believe there is a performance penalty paid for classes with
finalizers.

To make a long story short, you probably should not rely on finalizers
for cleanup.  Using finally blocks has some advantages: the code is
always executed and it is typically executed much earlier than a
finalizer would.

Kind regards

    robert
nukleus - 10 Feb 2007 17:22 GMT
>> only deprecated runFinalizersOnExit() method worked!
>> why not the others? even System.gc()?
[quoted text clipped - 12 lines]
>always executed and it is typically executed much earlier than a
>finalizer would.

Interesting idea.

Btw, I just read some posts on memory allocation/deallocation issues,
and I did not quite expect the behavior described.

I thought that object is gc'ed when there are no references left.

So, if i have a multi-variable object, containing strings,
buffers, etc. and I put those objects in a Vector,
for the sake of argument, and, i do setElementAt() and set
it to null, i thought it becomes a subject to gc,
and, once it is gc'ed, all the buffers, strings, etc.,
it contains become subject to gc also.

Is that true?

Secondly, if i have a string and then set it to a new value,
does the old value become a subject to gc?

Sting s = "abc";
s = "def";

What happens to "abc" string in terms of deallocation?
Is it the same as new String("def")
meaning that there is no longer a reference
to "abc" and it, therefore, is subject to gc?

How do I release memory held by StringBuffer?
When I set its size to 0 and start accumulating
a new data in it, what happens to the old data?
Is it gc'ed?

Intuitively, it seems that by merely doing setLength
to 0, it should not change anything as the reference
is effectively still there, as what StringBuffer looks
to me is what is known as counted string versus C string.

Can you clarify this issue?

Thanks.

>Kind regards
>
>        robert
Arne Vajhøj - 10 Feb 2007 18:25 GMT
> Btw, I just read some posts on memory allocation/deallocation issues,
> and I did not quite expect the behavior described.
>
> I thought that object is gc'ed when there are no references left.

Java does not use reference counting.

Objects that are not reachable from the executing program can be
GC'ed.

> So, if i have a multi-variable object, containing strings,
> buffers, etc. and I put those objects in a Vector,
> for the sake of argument, and, i do setElementAt() and set
> it to null, i thought it becomes a subject to gc,
> and, once it is gc'ed, all the buffers, strings, etc.,
> it contains become subject to gc also.

The GC can/should GC them all in one sweep.

> Secondly, if i have a string and then set it to a new value,
> does the old value become a subject to gc?

Yes.

> Sting s = "abc";
> s = "def";

There are some special handling for string literals where Java
only have one object for the same literal.

> What happens to "abc" string in terms of deallocation?
> Is it the same as new String("def")
> meaning that there is no longer a reference
> to "abc" and it, therefore, is subject to gc?

Ignoring the special handling of String literals, then
as soon as there are no way to reach an object it can be GC'ed.

> How do I release memory held by StringBuffer?

Just let the reference run out of scope.

> When I set its size to 0 and start accumulating
> a new data in it, what happens to the old data?
> Is it gc'ed?

Depends on the implementation. You can look it up whether
it reuses the backing storage or not. I have not checked
it out myself. You should not code after that kind of
implementation issues.

Arne
nukleus - 10 Feb 2007 21:24 GMT
>> Btw, I just read some posts on memory allocation/deallocation issues,
>> and I did not quite expect the behavior described.
[quoted text clipped - 5 lines]
>Objects that are not reachable from the executing program can be
>GC'ed.

Interesting. But how do they know they are not reachable?

>> So, if i have a multi-variable object, containing strings,
>> buffers, etc. and I put those objects in a Vector,
[quoted text clipped - 4 lines]
>
>The GC can/should GC them all in one sweep.

Thanks god.

>> Secondly, if i have a string and then set it to a new value,
>> does the old value become a subject to gc?
[quoted text clipped - 6 lines]
>There are some special handling for string literals where Java
>only have one object for the same literal.

Well, i didn't mean string literal,
but string as such.

>> What happens to "abc" string in terms of deallocation?
>> Is it the same as new String("def")
>> meaning that there is no longer a reference
>> to "abc" and it, therefore, is subject to gc?

>Ignoring the special handling of String literals, then
>as soon as there are no way to reach an object it can be GC'ed.

Sorry, but I don't get it.
How does it know it can't reach something?

>> How do I release memory held by StringBuffer?
>
>Just let the reference run out of scope.

Well, but when I am in a loop, reusing the same string
buffer that has large amounts of buffer for each iteration,
what happens to the old data?
Should I just create a new buffer every iteration
just to make sure the old stuff gets gc'ed?
I am talking about 10s of megs of data being shuffled.

>> When I set its size to 0 and start accumulating
>> a new data in it, what happens to the old data?
[quoted text clipped - 4 lines]
>it out myself. You should not code after that kind of
>implementation issues.

Thanks.

>Arne
Eric Sosman - 10 Feb 2007 22:49 GMT
>>> Btw, I just read some posts on memory allocation/deallocation issues,
>>> and I did not quite expect the behavior described.
[quoted text clipped - 6 lines]
>
> Interesting. But how do they know they are not reachable?

    "They" the objects don't know.  The garbage collector
works hard to find out.

>>> Secondly, if i have a string and then set it to a new value,
>>> does the old value become a subject to gc?
[quoted text clipped - 7 lines]
> Well, i didn't mean string literal,
> but string as such.

    Any object instance that is unreachable by a chain of
sufficiently strong references[*] is eligible for garbage
collection.

    [*] To support caches of various kinds, Java provides
some specialized weaker-than-normal reference types.  I'm
not familiar with the ins and outs of all of them: weak
references, phantom references, unsubstantiated references,
unattributed references (a.k.a. plagiarism), and whatever
other flavors might exist.  Some of these are too weak to
shield an instance from garbage collection, yet strong
enough to locate it if the collector hasn't reaped it first.
It's my understanding that String.intern() uses one of these
weaker forms, so even a String[**] literal could perhaps be
collected.  (Probably not unless all the classes that contain
it are also collected, but I believe it's possible nonetheless.)

    [**] I don't know what happens to Sting objects.

>>> What happens to "abc" string in terms of deallocation?
>>> Is it the same as new String("def")
[quoted text clipped - 6 lines]
> Sorry, but I don't get it.
> How does it know it can't reach something?

    The garbage collector begins from a set of known "root"
references, and finds other references (or possible references)
in the Thread stacks.  Then it follows all these references to
their referenced objects, and follows all the references found
inside those objects, and so on, until it's located every object
that is referencable.  Everything not located is unreachable and
hence garbage, eligible for collection.

    The details of how this search is carried out vary from one
implementation to another.  I believe there's still a lot of
active research on how to make GC pleasanter in various ways.

>>> How do I release memory held by StringBuffer?
>> Just let the reference run out of scope.
[quoted text clipped - 5 lines]
> just to make sure the old stuff gets gc'ed?
> I am talking about 10s of megs of data being shuffled.

    For specificity, let's consider two different loops:

    // Loop A
    StringBuffer buff = new StringBuffer();
    for (...) {
       buff.setLength(0);
       ... fill up buff and use it ...
    }

    // Loop B
    for (...) {
       StringBuffer buff = new StringBuffer();
       ... fill up buff and use it ...
    }

Loop A uses the same StringBuffer over and over, changing its
contents each time around.  Loop B creates a fresh StringBuffer
at each iteration.  Which is more efficient?  Much depends on
the nature of "use it."  For example, if you "use it" by making
a String out of it, the String seizes ownership of the underlying
char[] array and retains it until the String itself becomes garbage.
In this (common) case, the only memory you're "recycling" are the
dribs and drabs that give a StringBuffer its StringBuffer-nature,
not the zillions of megabytes of character data its various
incarnations contain.  On the other hand, if you work entirely
within the StringBuffer and never generate a String from it, the
multimegs may well be recycled by Loop A, garbage-collected by
Loop B.

Signature

Eric Sosman
esosman@acm-dot-org.invalid

Chris Uppal - 11 Feb 2007 16:58 GMT
> weak
> references, phantom references, unsubstantiated references,
> unattributed references (a.k.a. plagiarism), and [...]

<loud grin/>

Nothing to add, but I couldn't let it pass without acknowledgement.

   -- chris
Arne Vajhøj - 11 Feb 2007 20:47 GMT
>>> I thought that object is gc'ed when there are no references left.
>> Java does not use reference counting.
[quoted text clipped - 3 lines]
>
> Interesting. But how do they know they are not reachable?

>> Ignoring the special handling of String literals, then
>> as soon as there are no way to reach an object it can be GC'ed.
>
> Sorry, but I don't get it.
> How does it know it can't reach something?

The GC is a smart guy.

:-)

But if you consider it, then you will find that you can do
it manually. And if you can do it manually there are a good
possibility that you can write code to do the same.

And they have to it that way.

Reference counting almost always lead to memory leaks,
because two unreachable objects have a reference to each other.

Arne
Oliver Wong - 12 Feb 2007 19:12 GMT
>>>> I thought that object is gc'ed when there are no references left.
>>> Java does not use reference counting.
[quoted text clipped - 11 lines]
>
> The GC is a smart guy.

   There are many techniques, and it *is* a domain of active research, and
it *is* relatively complicated. Do some google queries (e.g. "garbage
collection") and I'm sure you'll find some published articles and research
papers on various GC algorithms. Or contact your local university -- perhaps
a local computer science professor can direct you to some textbooks on the
subject.

   - Oliver


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.