A Java Brainteaser - a Static Factory method Narrative

Discussion in 'Java' started by krasicki, May 13, 2005.

  1. krasicki

    krasicki Guest

    I had never run into this before but have recently encountered code
    that is something like:

    // This code runs - I'm generalizing so forgive unintentional
    oversights

    // from a servlet
    MyWidget mw = FactoryClass.staticMethod();
    :

    and in FactoryClass we find:

    public static MyWidget staticMethod() {
    // yada yada
    return new MyWidgetObject();
    }


    My questions are many but first and foremost is, *how is the memory
    managed?* Is each new object a new static object with immutable memory
    assigned it or is the static memory recycled with each assignment to
    mw?

    Disclaimer: YES,YES,YES - I know, I know... but take it for what it's
    worth.
     
    krasicki, May 13, 2005
    #1
    1. Advertising

  2. krasicki

    Wibble Guest

    The method to create a widget is static. Not the widget allocated.
    Its a plain old java object.

    krasicki wrote:
    > I had never run into this before but have recently encountered code
    > that is something like:
    >
    > // This code runs - I'm generalizing so forgive unintentional
    > oversights
    >
    > // from a servlet
    > MyWidget mw = FactoryClass.staticMethod();
    > :
    >
    > and in FactoryClass we find:
    >
    > public static MyWidget staticMethod() {
    > // yada yada
    > return new MyWidgetObject();
    > }
    >
    >
    > My questions are many but first and foremost is, *how is the memory
    > managed?* Is each new object a new static object with immutable memory
    > assigned it or is the static memory recycled with each assignment to
    > mw?
    >
    > Disclaimer: YES,YES,YES - I know, I know... but take it for what it's
    > worth.
    >
     
    Wibble, May 13, 2005
    #2
    1. Advertising

  3. krasicki

    krasicki Guest

    Are there garbage collection issues with these objects?
     
    krasicki, May 13, 2005
    #3
  4. krasicki

    Wibble Guest

    krasicki wrote:
    > Are there garbage collection issues with these objects?
    >

    No, its irrelevant that they're allocated from a static
    method. It just allows the Factory class a little more
    control of object creation than the 'new' method by itself.

    In your example, the static just calls new. Its a POJO.
     
    Wibble, May 13, 2005
    #4
  5. krasicki

    krasicki Guest

    Alright, I'll buy that. Let me reiterate what you're saying, just to
    be clear.

    If my example was (instead of a servlet lifecycle);

    // from a short term object instance
    MyWidget mw = FactoryClass.staticMethod();

    then mw would be garbage collected just like any other object that got
    instantiated for it. Preferably, object mw will have its own
    housekeeping method that cleans up its particulars so that the same
    object that instantiated mw could eliminate it like so (more or less):

    mw.cleanUp();
    mw = null;


    Furthermore, a static method used as a Factory, generally speaking,
    should add value (performance, convenience, or otherwise) to the
    dispensing of the new object.

    Now, at face value, it would seem that all factory objects in
    non-distributed application container contexts should be implemented
    this way assuming the class is efficient.

    As a rule of thumb, would I be correct in suggesting that factory
    methods should be static when they serve the broadest utilitarian
    purposes and classes should be instantiated for their method access for
    more specialized processing purposes?

    Finally, when would using this technique be good or bad practice.
    After all, this technique seems to violate strict object-oriented
    implementation practice.
     
    krasicki, May 13, 2005
    #5
  6. krasicki wrote:
    > Alright, I'll buy that. Let me reiterate what you're saying, just to
    > be clear.
    >
    > If my example was (instead of a servlet lifecycle);
    >
    > // from a short term object instance
    > MyWidget mw = FactoryClass.staticMethod();
    >
    > then mw would be garbage collected just like any other object that got
    > instantiated for it. Preferably, object mw will have its own
    > housekeeping method that cleans up its particulars so that the same
    > object that instantiated mw could eliminate it like so (more or less):
    >
    > mw.cleanUp();
    > mw = null;
    >
    >
    > Furthermore, a static method used as a Factory, generally speaking,
    > should add value (performance, convenience, or otherwise) to the
    > dispensing of the new object.
    >
    > Now, at face value, it would seem that all factory objects in
    > non-distributed application container contexts should be implemented
    > this way assuming the class is efficient.
    >
    > As a rule of thumb, would I be correct in suggesting that factory
    > methods should be static when they serve the broadest utilitarian
    > purposes and classes should be instantiated for their method access for
    > more specialized processing purposes?
    >
    > Finally, when would using this technique be good or bad practice.
    > After all, this technique seems to violate strict object-oriented
    > implementation practice.
    >


    All java objects are the same in terms of memory management (creation
    and removal). It is irrelevant that a static method just happened to be
    used to create the object.

    The garbage collector is responsible for objects actual destruction. As
    a programmer you have no control over when the garbage collector runs.
    At best you can ask the CG to run, but it is up to the CG (based on its
    own algorithms) whether it will run.

    Java objects do not have C++ style destructor. They can override
    Object.finalize(), this method MAY be called at sometime if the object
    is being CGed, but there is no guarantee. So its better to directly call
    your own 'cleanup' method to close File, sockets type resources.

    As for static factory methods, they are fine if used sparingly. Its
    usually more helpful to have a factory method on an instance of the
    factory - then you can override if necessary in a derived factory class.
     
    Andrew McDonagh, May 13, 2005
    #6
  7. krasicki

    Ross Bamford Guest

    On Thu, 2005-05-12 at 21:08 -0700, krasicki wrote:

    >
    > As a rule of thumb, would I be correct in suggesting that factory
    > methods should be static when they serve the broadest utilitarian
    > purposes and classes should be instantiated for their method access for
    > more specialized processing purposes?
    >
    > Finally, when would using this technique be good or bad practice.
    > After all, this technique seems to violate strict object-oriented
    > implementation practice.
    >


    Factory methods are great where you want a singleton:

    public class ServiceProvider
    {
    private static final ServiceProvider prov =
    new ServiceProvider(class.getResourceAsStream("sp.xml"));

    private ServiceProvider(InputStream XML) {
    // ... Configure from XML ...
    }

    public Degigitator doService(Rerulurator r) {
    // ... service according to config ...
    }

    // Factory
    public static ServiceProvider getInstance() {
    return prov;
    }
    }

    This is ideal for stuff you want global, since there will be only one
    instance per JVM, and you can get it from anywhere:

    myDegig = ServiceProvider.getInstance().doService(myRulurator));

    If your needs are more complex, you could have a static factory that
    creates instance factories with a certain configuration. In this
    situation I often define an abstract class as the factory 'interface',
    and provide on that the static factory.

    Handy uses are many: SPI, Registry, logging (in small apps), etc, etc,
    etc. It does require a little more consideration of the runtime
    lifecycle of the JVM, and there are one or two nasty gotchas (as always)
    but generally it's a useful technique (that seems to be going out of
    fashion now in favour of context-scoped 'singletons').

    Cheers,
    Ross

    --
    [Ross A. Bamford] [ross AT the.website.domain]
    Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
    http://www.roscopec0.f9.co.uk/ + in
     
    Ross Bamford, May 13, 2005
    #7
  8. krasicki

    krasicki Guest

    Andrew McDonagh wrote:
    > krasicki wrote:

    -snip-
    >
    > All java objects are the same in terms of memory management (creation


    > and removal). It is irrelevant that a static method just happened to

    be
    > used to create the object.


    I want to explore that subject. Take all my arguments as good natured
    curiosity.

    >
    > The garbage collector is responsible for objects actual destruction.

    As
    > a programmer you have no control over when the garbage collector

    runs.
    > At best you can ask the CG to run, but it is up to the CG (based on

    its
    > own algorithms) whether it will run.


    I disagree. When a Java programmer invokes a System.gc() call it frees
    memory to the JVM at the earliest algorithmically determined time. In
    fact, I read an IBM or BEA article recently that advised programmers
    not to use it because the application server's own garbage collection
    management would get screwed up and you would likely hurt more than
    help performance.

    But let's get even more subtle. Hagar, Bulka, and other java stylists
    recommend explicit cleanup in deeply nested objects. In other words,
    deeply nested cleanup routines that return exhausted object instances
    back to a state of null. This, we are told, hints to the GC that it's
    okay to free the associated memory.

    My question really comes back to a nagging doubt. Can an object
    created by a factory class from a static method ever be clean enough to
    free up? In other words, does the fact that it has referential roots
    from a static method make the byproducts of that method all look
    statically active (or immutable) to the GC?

    Rod Johnson, in J2EE Development without EJB, talks about generational
    garbage collection techniques. Can anyone put static factory methods
    into context considering these techniques?

    -snip-

    > As for static factory methods, they are fine if used sparingly.


    Don't you really mean appropriately. Will using them a lot be worse or
    better than using them a little. What does their proliferation have to
    do with it?

    > Its
    > usually more helpful to have a factory method on an instance of the
    > factory - then you can override if necessary in a derived factory

    class.

    Understood.
     
    krasicki, May 13, 2005
    #8
  9. krasicki wrote:
    <snip stuff>
    > My question really comes back to a nagging doubt. Can an object
    > created by a factory class from a static method ever be clean enough to
    > free up? In other words, does the fact that it has referential roots
    > from a static method make the byproducts of that method all look
    > statically active (or immutable) to the GC?


    It seems that somewhere along the road you have gotten thoroughly
    confused about how garbage collection works. As such, it is hard to
    answer your question, since you are likely to misinterpret the answer.
    Please read this for some basic information about garbage collection:
    http://java.sun.com/developer/technicalArticles/ALT/RefObj/

    To quote the most relevant parts:

    (QUOTE)
    The garbage collector's job is to identify objects that are no longer in
    use and reclaim the memory. What does it mean for an object to be in use?

    Note: An object is in use if it can be accessed or reached by the
    program in its current state.

    An executing Java program consists of a set of threads, each of which is
    actively executing a set of methods (one having called the next). Each
    of these methods can have arguments or local variables that are
    references to objects. These references are said to belong to a root set
    of references that are immediately accessible to the program. Other
    references in the root set include static reference variables defined in
    loaded classes, and references registered through the Java Native
    Interface (JNI) API.

    All objects referenced by this root set of references are said to be
    reachable by the program in its current state and must not be collected.
    Also, those objects might contain references to still other objects,
    which are also reachable, and so on.

    All other objects on the heap are considered unreachable, and all
    unreachable objects are eligible for garbage collection.
    (UNQUOTE)

    Note especially the part about /actively executing/ methods. Once a
    method returns, any local references in that method are no longer part
    of the root set.

    --
    Daniel Sjöblom
    Remove _NOSPAM to reply by mail
     
    =?ISO-8859-1?Q?Daniel_Sj=F6blom?=, May 13, 2005
    #9
  10. On 13 May 2005 13:34:18 -0700, krasicki <> wrote:

    > In other words, does the fact that it has referential roots
    > from a static method make the byproducts of that method all look
    > statically active (or immutable) to the GC?
    >


    No.

    Returning a value from a method doesnt create a reference (static
    or not) so the GC isnt interested in it.

    Paul C.



    > Rod Johnson, in J2EE Development without EJB, talks about generational
    > garbage collection techniques. Can anyone put static factory methods
    > into context considering these techniques?
    >
    > -snip-
    >
    >> As for static factory methods, they are fine if used sparingly.

    >
    > Don't you really mean appropriately. Will using them a lot be worse or
    > better than using them a little. What does their proliferation have to
    > do with it?


    Use one when it solves a specific problem for you.

    Using them indiscriminately makes code harder to read.

    Paul C.
     
    paul campbell, May 13, 2005
    #10
  11. krasicki wrote:

    > Andrew McDonagh wrote:
    >>All java objects are the same in terms of memory management (creation
    >>and removal). It is irrelevant that a static method just happened to be
    >>used to create the object.

    >
    >
    > I want to explore that subject. Take all my arguments as good natured
    > curiosity.
    >
    >
    >>The garbage collector is responsible for objects actual destruction. As
    >>a programmer you have no control over when the garbage collector runs.
    >>At best you can ask the CG to run, but it is up to the CG (based on its
    >>own algorithms) whether it will run.

    >
    >
    > I disagree. When a Java programmer invokes a System.gc() call it frees
    > memory to the JVM at the earliest algorithmically determined time.


    It depends what you mean by that. System.gc() requests that the GC make
    its best effort to reclaim unreachable objects. Depending on the GC
    implementation, that "best effort" could conceivably be no special
    action whatsoever. This is what I believe Andrew was describing.

    > In
    > fact, I read an IBM or BEA article recently that advised programmers
    > not to use it because the application server's own garbage collection
    > management would get screwed up and you would likely hurt more than
    > help performance.


    More the *VM's* GC. I am not aware of any application server that
    provides any particular "garbage collection management", nor do I really
    see how any could be provided outside tweaking or configuring the VM,
    whether the app server wanted to or not. The article may have been
    quite correct, however, in that a program frequently invoking
    System.gc() might cause the garbage collector to expend considerably
    more effort than it otherwise would do, for no particular gain.

    > But let's get even more subtle. Hagar, Bulka, and other java stylists
    > recommend explicit cleanup in deeply nested objects. In other words,
    > deeply nested cleanup routines that return exhausted object instances
    > back to a state of null. This, we are told, hints to the GC that it's
    > okay to free the associated memory.


    I disagree. There are cases where it is advantageous to set references
    to null, which may allow the GC to clean up an object sooner than it
    otherwise would do, but usually it is clearer and easier to simply let
    references go out of scope. It's part of the GC's *job* to recognize
    which objects it can reclaim, and nullifying references that are about
    to go out of scope or become themselves unreachable anyway just isn't
    worth the cost in development time, code clarity, and maintenance.

    > My question really comes back to a nagging doubt. Can an object
    > created by a factory class from a static method ever be clean enough to
    > free up? In other words, does the fact that it has referential roots
    > from a static method make the byproducts of that method all look
    > statically active (or immutable) to the GC?


    There are no "referential roots". Java does not know or care about the
    origin of a reference. It cares only about whether the reference, and
    thus its referent, is accessible from a live thread.

    > Rod Johnson, in J2EE Development without EJB, talks about generational
    > garbage collection techniques. Can anyone put static factory methods
    > into context considering these techniques?


    Static methods are not in any way special relative to generational
    garbage collection. Generational GC is concerned with how old an object
    is, and thus _when_ it was created. Generation GC, like Java in
    general, doesn't care a whit about _how_ it was created.


    --
    John Bollinger
     
    John C. Bollinger, May 14, 2005
    #11
  12. krasicki

    Wibble Guest

    Stop looking for stupid rules and do what makes sense.
    The rules I use when programming java are:

    You arent gonna need it.

    Do the simplest thing that can possibly work.

    (Yeah, I stole them from Beck)

    If you NEED a factory for a reason, create one, otherwise
    dont. If you dont understand why you need one, you dont
    need one.

    Ross Bamford wrote:
    > On Thu, 2005-05-12 at 21:08 -0700, krasicki wrote:
    >
    >
    >>As a rule of thumb, would I be correct in suggesting that factory
    >>methods should be static when they serve the broadest utilitarian
    >>purposes and classes should be instantiated for their method access for
    >>more specialized processing purposes?
    >>
    >>Finally, when would using this technique be good or bad practice.
    >>After all, this technique seems to violate strict object-oriented
    >>implementation practice.
    >>

    >
    >
    > Factory methods are great where you want a singleton:
    >
    > public class ServiceProvider
    > {
    > private static final ServiceProvider prov =
    > new ServiceProvider(class.getResourceAsStream("sp.xml"));
    >
    > private ServiceProvider(InputStream XML) {
    > // ... Configure from XML ...
    > }
    >
    > public Degigitator doService(Rerulurator r) {
    > // ... service according to config ...
    > }
    >
    > // Factory
    > public static ServiceProvider getInstance() {
    > return prov;
    > }
    > }
    >
    > This is ideal for stuff you want global, since there will be only one
    > instance per JVM, and you can get it from anywhere:
    >
    > myDegig = ServiceProvider.getInstance().doService(myRulurator));
    >
    > If your needs are more complex, you could have a static factory that
    > creates instance factories with a certain configuration. In this
    > situation I often define an abstract class as the factory 'interface',
    > and provide on that the static factory.
    >
    > Handy uses are many: SPI, Registry, logging (in small apps), etc, etc,
    > etc. It does require a little more consideration of the runtime
    > lifecycle of the JVM, and there are one or two nasty gotchas (as always)
    > but generally it's a useful technique (that seems to be going out of
    > fashion now in favour of context-scoped 'singletons').
    >
    > Cheers,
    > Ross
    >
     
    Wibble, May 14, 2005
    #12
  13. krasicki

    Ross Bamford Guest

    > <fixed toppost>

    > Ross Bamford wrote:
    > > On Thu, 2005-05-12 at 21:08 -0700, krasicki wrote:
    > >
    > >
    > >>As a rule of thumb, would I be correct in suggesting that factory
    > >>methods should be static when they serve the broadest utilitarian
    > >>purposes and classes should be instantiated for their method access for
    > >>more specialized processing purposes?
    > >>
    > >>Finally, when would using this technique be good or bad practice.
    > >>After all, this technique seems to violate strict object-oriented
    > >>implementation practice.
    > >>

    > >
    > >
    > > Factory methods are great where you want a singleton:
    > >
    > > public class ServiceProvider
    > > {
    > > private static final ServiceProvider prov =
    > > new ServiceProvider(class.getResourceAsStream("sp.xml"));
    > >
    > > private ServiceProvider(InputStream XML) {
    > > // ... Configure from XML ...
    > > }
    > >
    > > public Degigitator doService(Rerulurator r) {
    > > // ... service according to config ...
    > > }
    > >
    > > // Factory
    > > public static ServiceProvider getInstance() {
    > > return prov;
    > > }
    > > }
    > >
    > > This is ideal for stuff you want global, since there will be only one
    > > instance per JVM, and you can get it from anywhere:
    > >
    > > myDegig = ServiceProvider.getInstance().doService(myRulurator));
    > >
    > > If your needs are more complex, you could have a static factory that
    > > creates instance factories with a certain configuration. In this
    > > situation I often define an abstract class as the factory 'interface',
    > > and provide on that the static factory.
    > >
    > > Handy uses are many: SPI, Registry, logging (in small apps), etc, etc,
    > > etc. It does require a little more consideration of the runtime
    > > lifecycle of the JVM, and there are one or two nasty gotchas (as always)
    > > but generally it's a useful technique (that seems to be going out of
    > > fashion now in favour of context-scoped 'singletons').
    > >
    > > Cheers,
    > > Ross
    > >

    On Fri, 2005-05-13 at 19:27 -0400, Wibble wrote:
    > Stop looking for stupid rules and do what makes sense.
    > The rules I use when programming java are:
    >
    > You arent gonna need it.
    >
    > Do the simplest thing that can possibly work.
    >
    > (Yeah, I stole them from Beck)
    >
    > If you NEED a factory for a reason, create one, otherwise
    > dont. If you dont understand why you need one, you dont
    > need one.
    >


    You know, you can actually do most stuff by stringing commands together
    with a shell. That way, you don't need to worry about the bytecode
    interpreter, runtime, factories, classes, instantiation, oop, methods,
    or any of that other stupid advanced crap.

    Ross

    --
    [Ross A. Bamford] [ross AT the.website.domain]
    Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
    http://www.roscopec0.f9.co.uk/ + in
     
    Ross Bamford, May 14, 2005
    #13
  14. krasicki

    Ross Bamford Guest

    On Sat, 2005-05-14 at 00:35 +0300, Daniel Sjöblom wrote:
    > krasicki wrote:
    > <snip stuff>
    > > My question really comes back to a nagging doubt. Can an object
    > > created by a factory class from a static method ever be clean enough to
    > > free up? In other words, does the fact that it has referential roots
    > > from a static method make the byproducts of that method all look
    > > statically active (or immutable) to the GC?

    >
    > It seems that somewhere along the road you have gotten thoroughly
    > confused about how garbage collection works. As such, it is hard to
    > answer your question, since you are likely to misinterpret the answer.
    > Please read this for some basic information about garbage collection:
    > http://java.sun.com/developer/technicalArticles/ALT/RefObj/
    >
    > To quote the most relevant parts:
    >
    > (QUOTE)
    > The garbage collector's job is to identify objects that are no longer in
    > use and reclaim the memory. What does it mean for an object to be in use?
    >
    > Note: An object is in use if it can be accessed or reached by the
    > program in its current state.
    >
    > An executing Java program consists of a set of threads, each of which is
    > actively executing a set of methods (one having called the next). Each
    > of these methods can have arguments or local variables that are
    > references to objects. These references are said to belong to a root set
    > of references that are immediately accessible to the program. Other
    > references in the root set include static reference variables defined in
    > loaded classes, and references registered through the Java Native
    > Interface (JNI) API.
    >
    > All objects referenced by this root set of references are said to be
    > reachable by the program in its current state and must not be collected.
    > Also, those objects might contain references to still other objects,
    > which are also reachable, and so on.
    >
    > All other objects on the heap are considered unreachable, and all
    > unreachable objects are eligible for garbage collection.
    > (UNQUOTE)
    >
    > Note especially the part about /actively executing/ methods. Once a
    > method returns, any local references in that method are no longer part
    > of the root set.
    >


    I think the source of OPs confusion may be the sentence (fragment)
    "Other references in the root set include static reference variables
    defined in loaded classes, ...", taken as meaning all reference
    variables rather than reference member variables only.

    As a more general thing, this confusion is probably an example of the
    adage that "a little knowledge is a dangerous thing" (and I mean no
    offence by this at all). I am merely suggesting the OP might want to
    revisit some of the more fundemental Java concepts before hitting the
    metal with BEA references or the more technical J2EE journals.

    Ross

    --
    [Ross A. Bamford] [ross AT the.website.domain]
    Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
    http://www.roscopec0.f9.co.uk/ + in
     
    Ross Bamford, May 14, 2005
    #14
  15. krasicki

    krasicki Guest

    paul campbell wrote:
    > On 13 May 2005 13:34:18 -0700, krasicki <> wrote:
    >
    > > In other words, does the fact that it has referential roots
    > > from a static method make the byproducts of that method all look
    > > statically active (or immutable) to the GC?
    > >

    >
    > No.
    >
    > Returning a value from a method doesnt create a reference (static
    > or not) so the GC isnt interested in it.


    Paul,

    Explain this a bit.

    A class that contains a static method does not have to be instantiated.

    That method occupies a certain amont of memory in the JVM allocation.
    Do all of the POGOs created from that method extend that static
    footprint or do they simply get created initially as short-term memory
    footprints?

    Once I say x = FactoryClass.staticMethodObject();

    I have an object that may involve many objects within objects.

    When I say, x = null;

    I'm hinting to the GC that I'm done with it. But does the GC look at
    it and say, hey, it's part of static memory, leave it there or is the
    implicit assumption to return it to free memory.
    >
    >
    >
    > > Rod Johnson, in J2EE Development without EJB, talks about

    generational
    > > garbage collection techniques. Can anyone put static factory

    methods
    > > into context considering these techniques?
    > >
    > > -snip-
    > >
    > >> As for static factory methods, they are fine if used sparingly.

    > >
    > > Don't you really mean appropriately. Will using them a lot be

    worse or
    > > better than using them a little. What does their proliferation

    have to
    > > do with it?

    >
    > Use one when it solves a specific problem for you.
    >
    > Using them indiscriminately makes code harder to read.
    >

    Once again, I must (in good humor) protest. Couldn't somebody say,
    "Hey, if you can read it once, can't you read it twice? three times?
    and so on? What's so hard to read?

    Isn't this more a case of familiarity breeding contempt?
     
    krasicki, May 14, 2005
    #15
  16. krasicki

    krasicki Guest

    John C. Bollinger wrote:
    > krasicki wrote:
    >
    > > Andrew McDonagh wrote:

    -snip-
    > >>The garbage collector is responsible for objects actual

    destruction. As
    > >>a programmer you have no control over when the garbage collector

    runs.
    > >>At best you can ask the CG to run, but it is up to the CG (based on

    its
    > >>own algorithms) whether it will run.

    > >
    > >
    > > I disagree. When a Java programmer invokes a System.gc() call it

    frees
    > > memory to the JVM at the earliest algorithmically determined time.

    >
    > It depends what you mean by that. System.gc() requests that the GC

    make
    > its best effort to reclaim unreachable objects. Depending on the GC
    > implementation, that "best effort" could conceivably be no special
    > action whatsoever. This is what I believe Andrew was describing.


    I'm suspicious of that idea. When I read Rod Johnson's assertions
    today's JVM machinations are far from do nothing algorithms. They are
    sifting and sorting this stuff for efficiency.

    The larger argument is this. The static method I'm describing is
    invoked for every web-based visitor. The server is rebooted every
    night due to performance problems. I know - hard to believe but I'm
    the firefighter not the originator of any of this.

    I'm trying to determine if this static factory method might be
    contributing to this problem.

    >
    > > In
    > > fact, I read an IBM or BEA article recently that advised

    programmers
    > > not to use it because the application server's own garbage

    collection
    > > management would get screwed up and you would likely hurt more than
    > > help performance.

    >
    > More the *VM's* GC. I am not aware of any application server that
    > provides any particular "garbage collection management", nor do I

    really
    > see how any could be provided outside tweaking or configuring the VM,


    > whether the app server wanted to or not.


    Sorry. I've been overly busy lately so I haven't had time to do more
    than type stream of consciousness thoughts.

    You are correct about the JVM and GC. But I think that container
    managed issues contribute to this best practice suggestion that
    System.gc() not be used.

    > The article may have been
    > quite correct, however, in that a program frequently invoking
    > System.gc() might cause the garbage collector to expend considerably
    > more effort than it otherwise would do, for no particular gain.


    Yes.

    >
    > > But let's get even more subtle. Hagar, Bulka, and other java

    stylists
    > > recommend explicit cleanup in deeply nested objects. In other

    words,
    > > deeply nested cleanup routines that return exhausted object

    instances
    > > back to a state of null. This, we are told, hints to the GC that

    it's
    > > okay to free the associated memory.

    >
    > I disagree. There are cases where it is advantageous to set

    references
    > to null, which may allow the GC to clean up an object sooner than it
    > otherwise would do, but usually it is clearer and easier to simply

    let
    > references go out of scope. It's part of the GC's *job* to recognize


    > which objects it can reclaim, and nullifying references that are

    about
    > to go out of scope or become themselves unreachable anyway just isn't


    > worth the cost in development time, code clarity, and maintenance.


    Oh, let's argue this. The proverbial saying, "as above, so below"
    should not be taken so lightly. I will argue that cleaning up after
    oneself is not confusing, nor creates maintenance problems. It makes
    it explicit that no objects are being orphaned.


    >
    > > My question really comes back to a nagging doubt. Can an object
    > > created by a factory class from a static method ever be clean

    enough to
    > > free up? In other words, does the fact that it has referential

    roots
    > > from a static method make the byproducts of that method all look
    > > statically active (or immutable) to the GC?

    >
    > There are no "referential roots". Java does not know or care about

    the
    > origin of a reference. It cares only about whether the reference,

    and
    > thus its referent, is accessible from a live thread.


    But it is not Java we're refering to. Isn't the GC part of the JVM
    functionality?

    >
    > > Rod Johnson, in J2EE Development without EJB, talks about

    generational
    > > garbage collection techniques. Can anyone put static factory

    methods
    > > into context considering these techniques?

    >
    > Static methods are not in any way special relative to generational
    > garbage collection. Generational GC is concerned with how old an

    object
    > is, and thus _when_ it was created. Generation GC, like Java in
    > general, doesn't care a whit about _how_ it was created.
    >

    Then why would nulling an object provide a hint to the GC that an
    object is exhausted?
     
    krasicki, May 14, 2005
    #16
  17. krasicki <> scribbled the following
    on comp.lang.java.programmer:
    > paul campbell wrote:
    >> On 13 May 2005 13:34:18 -0700, krasicki <> wrote:
    >> > In other words, does the fact that it has referential roots
    >> > from a static method make the byproducts of that method all look
    >> > statically active (or immutable) to the GC?

    >>
    >> No.
    >>
    >> Returning a value from a method doesnt create a reference (static
    >> or not) so the GC isnt interested in it.


    > Paul,


    > Explain this a bit.


    > A class that contains a static method does not have to be instantiated.


    > That method occupies a certain amont of memory in the JVM allocation.
    > Do all of the POGOs created from that method extend that static
    > footprint or do they simply get created initially as short-term memory
    > footprints?


    > Once I say x = FactoryClass.staticMethodObject();


    > I have an object that may involve many objects within objects.


    > When I say, x = null;


    > I'm hinting to the GC that I'm done with it. But does the GC look at
    > it and say, hey, it's part of static memory, leave it there or is the
    > implicit assumption to return it to free memory.


    As far as the GC and memory management are concerned, it makes *NO
    DIFFERENCE WHATSOEVER* whether the object was constructed in a static
    method or in an instance method. Not even the slightest bit. The
    object does not retain any sort of information about which method
    created it, unless you explicitly tell it, by calling a method or
    setting a member variable. This is true for both objects created in
    static methods and ones created in instance methods.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-------------------------------------------------------- rules! --------/
    "You will be given the plague."
    - Montgomery Burns
     
    Joona I Palaste, May 14, 2005
    #17
  18. krasicki

    Ross Bamford Guest

    On Sat, 2005-05-14 at 07:14 -0700, krasicki wrote:
    > John C. Bollinger wrote:
    > > krasicki wrote:
    > >
    > > > Andrew McDonagh wrote:

    > -snip-
    > > >>The garbage collector is responsible for objects actual

    > destruction. As
    > > >>a programmer you have no control over when the garbage collector

    > runs.
    > > >>At best you can ask the CG to run, but it is up to the CG (based on

    > its
    > > >>own algorithms) whether it will run.
    > > >
    > > >
    > > > I disagree. When a Java programmer invokes a System.gc() call it

    > frees
    > > > memory to the JVM at the earliest algorithmically determined time.

    > >
    > > It depends what you mean by that. System.gc() requests that the GC

    > make
    > > its best effort to reclaim unreachable objects. Depending on the GC
    > > implementation, that "best effort" could conceivably be no special
    > > action whatsoever. This is what I believe Andrew was describing.

    >
    > I'm suspicious of that idea. When I read Rod Johnson's assertions
    > today's JVM machinations are far from do nothing algorithms. They are
    > sifting and sorting this stuff for efficiency.
    >


    But the point is it *looks* the same. It can be doing whatever it wants
    but because the GC is completely encapsulated in the implementation it
    must always maintain the various contracts involved. It must be
    transparent. For most real purposes, it *is* the same - it's only when
    you start getting into JNI (dont!), BCEL, Classloading and so on that
    you must consider the *exact* lifecycle of objects and references.

    > The larger argument is this. The static method I'm describing is
    > invoked for every web-based visitor. The server is rebooted every
    > night due to performance problems. I know - hard to believe but I'm
    > the firefighter not the originator of any of this.
    >
    > I'm trying to determine if this static factory method might be
    > contributing to this problem.
    >


    Is this a windoze box? In my experience, this kind of problem is
    actually fairly rare with Java. I guess it's purely because the JVM
    handles all the mallocs on the programmer's behalf, so it's a simple
    thing to ensure memory is not leaked (relatively, from the JVM team's
    POV).

    This is not to say you *can't* leak memory, just that you *shouldn't*
    unless you try (notwithstanding JVM bugs etc).

    > > I disagree. There are cases where it is advantageous to set

    > references
    > > to null, which may allow the GC to clean up an object sooner than it
    > > otherwise would do, but usually it is clearer and easier to simply

    > let
    > > references go out of scope. It's part of the GC's *job* to recognize

    >
    > > which objects it can reclaim, and nullifying references that are

    > about
    > > to go out of scope or become themselves unreachable anyway just isn't

    >
    > > worth the cost in development time, code clarity, and maintenance.

    >
    > Oh, let's argue this. The proverbial saying, "as above, so below"
    > should not be taken so lightly. I will argue that cleaning up after
    > oneself is not confusing, nor creates maintenance problems. It makes
    > it explicit that no objects are being orphaned.
    >


    This comes back to the fundementals of Garbage Collection - an object is
    eligable for collection when it is 'orphaned' (this is simplistic but
    essentially true). Nulling *references* is a valid technique if you have
    need to 'free' objects (e.g. in a long loop) but I am with John on the
    general case, in that it's better to let a variable go out of scope.

    Look at it this way - when a reference loses scope the JVM throws it
    away in effect, leaving the object 'unreachable' and hence eligable for
    the bin (next time the JVM goes into the kitchen). So what's the point
    of writing "finished with" all over it first? The JVM will still rewrite
    the message, which is after all an implementation note to itself (in a
    way).

    (I know it doesn't quite work when the technical aspects are considered,
    so let's not consider the technical aspects for a moment - I believe you
    need to step back and view the wood for a while...)

    > >
    > > > My question really comes back to a nagging doubt. Can an object
    > > > created by a factory class from a static method ever be clean

    > enough to
    > > > free up? In other words, does the fact that it has referential

    > roots
    > > > from a static method make the byproducts of that method all look
    > > > statically active (or immutable) to the GC?

    > >
    > > There are no "referential roots". Java does not know or care about

    > the
    > > origin of a reference. It cares only about whether the reference,

    > and
    > > thus its referent, is accessible from a live thread.

    >
    > But it is not Java we're refering to. Isn't the GC part of the JVM
    > functionality?
    >


    This is a misunderstanding. In Java the term 'referential roots' has no
    meaning. The JLS simply uses it to refer to a top-level reference that
    is in scope. If an object has no roots in the referential set (I.e. in
    scope vars of *all kinds*) then it is, by definition, unreachable.
    This is how the whole thing about losing a Map full of objects works,
    simply by throwing away the map ref (your root reference in this case).

    The GC Implementation is part of the JVM, but Garbage Collection,
    referential roots, reference counting and all that predate Java. The
    root set is simply a detail of the JVM implementation and has no bearing
    on this argument whatsoever.

    > >
    > > > Rod Johnson, in J2EE Development without EJB, talks about

    > generational
    > > > garbage collection techniques. Can anyone put static factory

    > methods
    > > > into context considering these techniques?

    > >
    > > Static methods are not in any way special relative to generational
    > > garbage collection. Generational GC is concerned with how old an

    > object
    > > is, and thus _when_ it was created. Generation GC, like Java in
    > > general, doesn't care a whit about _how_ it was created.
    > >

    > Then why would nulling an object provide a hint to the GC that an
    > object is exhausted?
    >


    In the same way that when a reference goes out of scope, the reference
    you set to null is removed from that object's reference count when you
    make the assignment (or just after I think). Periodically, the JVM runs
    through all it's objects (for example), and every one it finds with a
    zero reference count (indicating it's not reachable) is eligable for GC.
    Note this doesn't necessarily mean they *will* be collected, especially
    when we factor in active threads and whatnot, but you get the idea.

    I would expect that even internally there is no 'ordinary' way to know
    at GC time how or where an object was allocated.

    Cheers,
    Ross

    --
    [Ross A. Bamford] [ross AT the.website.domain]
    Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
    http://www.roscopec0.f9.co.uk/ + in
     
    Ross Bamford, May 14, 2005
    #18
  19. krasicki wrote:
    > Andrew McDonagh wrote:
    >
    >>krasicki wrote:

    >
    > -snip-
    >
    >>All java objects are the same in terms of memory management (creation

    >
    >
    >>and removal). It is irrelevant that a static method just happened to

    >
    > be
    >
    >>used to create the object.

    >
    >
    > I want to explore that subject. Take all my arguments as good natured
    > curiosity.
    >


    take mine with the same good natured, willing advice.

    Hopefully by now, all of the other replies within this thread has shown
    you that the GC works to its own rules. If we haven't then thats our
    fault - we need to find a way to describe it to you.

    >
    >>The garbage collector is responsible for objects actual destruction.

    >
    > As
    >
    >>a programmer you have no control over when the garbage collector

    >
    > runs.
    >
    >>At best you can ask the CG to run, but it is up to the CG (based on

    >
    > its
    >
    >>own algorithms) whether it will run.

    >
    >
    > I disagree. When a Java programmer invokes a System.gc() call it frees
    > memory to the JVM at the earliest algorithmically determined time.


    This is what I was talking about - at the 'earliest'. However, you need
    to remember that 'earliest' might be only be at application shutdown time.

    In
    > fact, I read an IBM or BEA article recently that advised programmers
    > not to use it because the application server's own garbage collection
    > management would get screwed up and you would likely hurt more than
    > help performance.
    >
    > But let's get even more subtle.


    Is that wise ;-)

    > Hagar, Bulka, and other java stylists
    > recommend explicit cleanup in deeply nested objects. In other words,
    > deeply nested cleanup routines that return exhausted object instances
    > back to a state of null. This, we are told, hints to the GC that it's
    > okay to free the associated memory.


    What they mean by this, is that its easy in Java (and any other auto
    memory manged language) to hold onto memory for unnecessarily long
    times. This really is the only practical reason for nulling a reference

    consider (very simple example)....

    public void someMethodThatRunsForaLongTime() {

    List aList = new ArrayList();

    for (int i=0; i!= 100000;i++) {
    aList.add("string = " + i);
    }

    // so now we have a huge arrayList with 100,000 string objects
    // referenced by it - so thats 100,001 objects we have created


    int listSize = aList.size();

    for (int i=0;i!= 100000;i++) {
    System.out.println(i);
    }

    } // only here at the end of the method, will the local reference
    'aList' go out of scope and therefore the object that it points to, is
    no 'orphaned' - which means the next time the GC runs, its can release
    the memory of the arrayList and its contents.


    However, if we put the line

    aList = null;

    just after we save the size of the aList in the 'listSize' int, then we
    have made the object that the 'aList' reference points to, orphaned much
    early that having to wait for the method to finish.

    This is a very contrived example to show the concept of holding onto
    objects for longer than is actually needed, but hopefully it serves its
    purpose.


    >
    > My question really comes back to a nagging doubt. Can an object
    > created by a factory class from a static method ever be clean enough to
    > free up? In other words, does the fact that it has referential roots
    > from a static method make the byproducts of that method all look
    > statically active (or immutable) to the GC?
    >


    At best as a developer we can System.gc, but the GC does not guarantee
    to do anything right then as a result of the call.

    In general sun's JVMs GC does most of the time, tend to run when
    System.gc is called, but as developers we can't rely upon it happening
    or continuing to work that way with either different runs of the
    application or indeed with future JVM releases.

    Therefore, we should not design our java apps with System.gc calls to
    release memory, as they will not behavior the same from one run to another.


    > Rod Johnson, in J2EE Development without EJB, talks about generational
    > garbage collection techniques. Can anyone put static factory methods
    > into context considering these techniques?
    >


    Again, static methods make no difference to the life times of objects.

    > -snip-
    >
    >
    >>As for static factory methods, they are fine if used sparingly.

    >
    >
    > Don't you really mean appropriately.


    Actually I mean both of those.

    >Will using them a lot be worse or
    > better than using them a little. What does their proliferation have to
    > do with it?


    The main problem with lots of static methods (although I'd call them
    'functions'), is that they make the implementation of your application,
    procedural rather than OO.

    By this I meam, we lose all of the benefits of objects, as these
    functions do not live on an object instance - they live on the class.

    They can be useful for utility functions like 'System.out.println("..");
    '. and are very useful for factory methods like yours or on a Singleton.

    Other than that, try to prefer an instance method of an object.

    >
    >
    >>Its
    >>usually more helpful to have a factory method on an instance of the
    >>factory - then you can override if necessary in a derived factory

    >
    > class.
    >
    > Understood.
    >
     
    Andrew McDonagh, May 14, 2005
    #19
  20. krasicki wrote:
    > I had never run into this before but have recently encountered code
    > that is something like:
    >
    > // This code runs - I'm generalizing so forgive unintentional
    > oversights
    >
    > // from a servlet
    > MyWidget mw = FactoryClass.staticMethod();
    > :
    >
    > and in FactoryClass we find:
    >
    > public static MyWidget staticMethod() {
    > // yada yada
    > return new MyWidgetObject();
    > }
    >
    >
    > My questions are many but first and foremost is, *how is the memory
    > managed?* Is each new object a new static object with immutable memory
    > assigned it or is the static memory recycled with each assignment to
    > mw?
    >
    > Disclaimer: YES,YES,YES - I know, I know... but take it for what it's
    > worth.
    >


    Actually just realised something that may help you - or confuse you
    completely... ;-)

    Seeing as the only way to start a java application is via a class's
    'main method.

    class HelloWorldApp {

    public static void main(String[] args) {
    Message m = new Message();
    m.show();
    }
    }


    class Message {

    public void show() {
    String theMessage = "Hello world";
    System.out.println(theMessage);
    }

    Seeing as this is the case, just about every single object created by
    the application, will have some relationship to the static main method.

    In the case above, the message object referenced by 'm', has been
    created by the 'main' method. It in turns creates the String object
    referenced by 'theMessage'.

    if it was a GUI app, then we could have created a dialog, with various
    components inside the 'show()' method, and so the tree of related
    objects would grow even larger.

    Does this help show that creating objects and static methods have no
    baring upon each other and so how the GC works with those objects?
     
    Andrew McDonagh, May 14, 2005
    #20
    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. javaguy44
    Replies:
    6
    Views:
    10,760
    javaguy44
    Sep 22, 2004
  2. Matthias Kaeppler
    Replies:
    22
    Views:
    957
    Thomas G. Marshall
    May 24, 2005
  3. Medi Montaseri
    Replies:
    17
    Views:
    876
    Medi Montaseri
    Sep 3, 2003
  4. C#
    Replies:
    4
    Views:
    411
  5. Rasmus Kromann-Larsen

    JS Brainteaser

    Rasmus Kromann-Larsen, May 31, 2007, in forum: Javascript
    Replies:
    4
    Views:
    96
    Rasmus Kromann-Larsen
    May 31, 2007
Loading...

Share This Page