forcing finalize()

Discussion in 'Java' started by cy, Feb 10, 2007.

  1. cy

    cy Guest

    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
     
    cy, Feb 10, 2007
    #1
    1. Advertising

  2. cy

    Chris Uppal Guest

    cy wrote:

    > 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
     
    Chris Uppal, Feb 10, 2007
    #2
    1. Advertising

  3. On 10.02.2007 13:31, cy wrote:
    > 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
     
    Robert Klemme, Feb 10, 2007
    #3
  4. cy

    nukleus Guest

    In article <>, Robert Klemme
    <> wrote:
    >On 10.02.2007 13:31, cy wrote:
    >> 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.


    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
     
    nukleus, Feb 10, 2007
    #4
  5. nukleus wrote:
    > 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
     
    =?ISO-8859-1?Q?Arne_Vajh=F8j?=, Feb 10, 2007
    #5
  6. cy

    nukleus Guest

    In article <45ce0e0d$0$49206$>,
    =?ISO-8859-1?Q?Arne_Vajh=F8j?= <> wrote:
    >nukleus wrote:
    >> 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.


    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,
    >> 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.


    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?

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

    >
    >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?
    >> 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.


    Thanks.

    >Arne
     
    nukleus, Feb 10, 2007
    #6
  7. cy

    Eric Sosman Guest

    nukleus wrote:
    > In article <45ce0e0d$0$49206$>,
    > =?ISO-8859-1?Q?Arne_Vajh=F8j?= <> wrote:
    >> nukleus wrote:
    >>> 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.

    >
    > 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?

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

    >> 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.


    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")
    >>> 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?


    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.

    >
    > 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.


    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.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Feb 10, 2007
    #7
  8. cy

    Chris Uppal Guest

    Eric Sosman wrote:

    > 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
     
    Chris Uppal, Feb 11, 2007
    #8
  9. nukleus wrote:
    > In article <45ce0e0d$0$49206$>,
    > =?ISO-8859-1?Q?Arne_Vajh=F8j?= <> wrote:
    >> nukleus wrote:
    >>> 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.

    >
    > 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
     
    =?ISO-8859-1?Q?Arne_Vajh=F8j?=, Feb 11, 2007
    #9
  10. cy

    Oliver Wong Guest

    "Arne Vajhøj" <> wrote in message
    news:45cf80eb$0$49206$...
    > nukleus wrote:
    >> In article <45ce0e0d$0$49206$>,
    >> =?ISO-8859-1?Q?Arne_Vajh=F8j?= <> wrote:
    >>> nukleus wrote:
    >>>> 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.

    >>
    >> 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.


    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
     
    Oliver Wong, Feb 12, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. z. f.

    throw exception in the finalize

    z. f., Jul 5, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    434
    avnrao
    Jul 5, 2004
  2. Noé R. Barranco

    Overriding finalize() method

    Noé R. Barranco, Aug 29, 2003, in forum: Java
    Replies:
    1
    Views:
    972
    Lee Fesperman
    Aug 30, 2003
  3. Joona I Palaste

    finalize() question

    Joona I Palaste, Dec 11, 2004, in forum: Java
    Replies:
    10
    Views:
    742
    Grant Wagner
    Dec 23, 2004
  4. andrey
    Replies:
    0
    Views:
    163
    andrey
    Dec 15, 2007
  5. Andrey Nikitin
    Replies:
    1
    Views:
    170
    Nobuyoshi Nakada
    Dec 16, 2007
Loading...

Share This Page