consumption

Discussion in 'Java' started by Ben Wilson, Aug 1, 2004.

  1. Ben Wilson

    Ben Wilson Guest

    Hi, everyone,

    I've google'd all around for an answer to this, but I'm not satisfied with
    what I've found. Hope someone can help.

    I've got a conceptual problem of consumption. I'm making instances of
    complicated objects, and whenever I need a new one, I just make a new one
    with the new keyword. All the initialisation is put nice & where it belongs
    in the initializers and the constructors. If I have an old object but want a
    new one, it's handy that I've got everything in the initializers and
    constructors. I just forget about the old one, let garbage collection take
    care of it, and create my new object by passing parameters to the
    constructors and maybe tweaking a few fields. This is comsumption and it's
    great.

    Now, what if I want to do this with the entire class? And reinitialise all
    of the static data? By using all of the initializers, instead of going in
    and manually resetting everything to its original state?

    The only things I've been able to find are pooh-poohing "you should never
    have to unload a class" and recommendations that "unloading classes should
    never reset static data". But what if that is exactly what I want? If we're
    talking about instances, what I certainly DON'T do would be to take an
    existing instance, invoke some method that does everything my constructor
    does and reset the values of fields to whatever they were originally.

    From a design perspective, it feels wrong to have to re-code all of the
    class-level initialization logic in some method with an arbitrary name. This
    is just duplicate code. What can you do in Java to make this happen for
    static?

    Thanks in advance,

    Ben.
     
    Ben Wilson, Aug 1, 2004
    #1
    1. Advertisements

  2. Ben Wilson

    Adam Guest

    "Ben Wilson" <> wrote in message
    news:410d05c6$0$32167$...
    > Hi, everyone,
    >
    > I've google'd all around for an answer to this, but I'm not satisfied with
    > what I've found. Hope someone can help.
    >
    > I've got a conceptual problem of consumption. I'm making instances of
    > complicated objects, and whenever I need a new one, I just make a new one
    > with the new keyword. All the initialisation is put nice & where it

    belongs
    > in the initializers and the constructors. If I have an old object but want

    a
    > new one, it's handy that I've got everything in the initializers and
    > constructors. I just forget about the old one, let garbage collection take
    > care of it, and create my new object by passing parameters to the
    > constructors and maybe tweaking a few fields. This is comsumption and it's
    > great.
    >
    > Now, what if I want to do this with the entire class? And reinitialise all
    > of the static data? By using all of the initializers, instead of going in
    > and manually resetting everything to its original state?
    >
    > The only things I've been able to find are pooh-poohing "you should never
    > have to unload a class" and recommendations that "unloading classes should
    > never reset static data". But what if that is exactly what I want? If

    we're
    > talking about instances, what I certainly DON'T do would be to take an
    > existing instance, invoke some method that does everything my constructor
    > does and reset the values of fields to whatever they were originally.
    >
    > From a design perspective, it feels wrong to have to re-code all of the
    > class-level initialization logic in some method with an arbitrary name.

    This
    > is just duplicate code. What can you do in Java to make this happen for
    > static?
    >
    > Thanks in advance,
    >
    > Ben.
    >
    >
    >


    Not sure if i'm understanding what you want, but you could create a static
    method which initialises all the static variables, and call this from
    static{}:

    class MyClass{
    static{
    //gets called when class is loaded
    initStatic();
    }

    static void initStatic(){
    //initialization stuff
    }
    }

    That way you can reset everything by calling initStatic, and you don't need
    to duplicate any code.

    adam
     
    Adam, Aug 1, 2004
    #2
    1. Advertisements

  3. Ben Wilson

    Ben Wilson Guest

    "Adam" <> wrote:

    >
    > Not sure if i'm understanding what you want, but you could create a static
    > method which initialises all the static variables, and call this from
    > static{}:
    >
    > class MyClass{
    > static{
    > //gets called when class is loaded
    > initStatic();
    > }
    >
    > static void initStatic(){
    > //initialization stuff
    > }
    > }
    >
    > That way you can reset everything by calling initStatic, and you don't

    need
    > to duplicate any code.
    >
    > adam
    >



    Thanks for the idea, Adam,

    Unfortunately, the objects of my class make use of finalize() and in this
    code they fiddle with the static elements. I want to get rid of everything,
    (classes, instances) and set it all to the way it was in the very beginning.
    If I do it the way you suggested, I'll still run the risk that instances
    left over from before my static "reinitialization" would be gc'd after
    calling the initStatic(). I could of course keep track of all of the
    instances in a static ArrayList or so, but that would prevent the normal gc
    from working so I don't see the solution there.

    What I really want to do is to [ctr][alt][del] the whole shabang and let the
    class initialization run its normal course. I honestly am not sure whether
    Java allows you to do that in a predictable way.

    B.
     
    Ben Wilson, Aug 1, 2004
    #3
  4. Ben Wilson

    David Hilsee Guest

    "Ben Wilson" <> wrote in message
    news:410d47cb$0$6409$...
    > Unfortunately, the objects of my class make use of finalize() and in this
    > code they fiddle with the static elements. I want to get rid of

    everything,
    > (classes, instances) and set it all to the way it was in the very

    beginning.
    > If I do it the way you suggested, I'll still run the risk that instances
    > left over from before my static "reinitialization" would be gc'd after
    > calling the initStatic(). I could of course keep track of all of the
    > instances in a static ArrayList or so, but that would prevent the normal

    gc
    > from working so I don't see the solution there.
    >
    > What I really want to do is to [ctr][alt][del] the whole shabang and let

    the
    > class initialization run its normal course. I honestly am not sure whether
    > Java allows you to do that in a predictable way.


    It sounds like you do not merely want to eliminate some code duplication.
    Now, it sounds like you are trying to do something much harder than that,
    like implement an object cache where you can clear all of the objects from
    the cache. That was just a guess. If you explained what your code is doing
    and what you are trying to accomplish, people may be able to help you. Of
    course, the suggested implementations may require you to rewrite some of the
    code.

    --
    David Hilsee
     
    David Hilsee, Aug 1, 2004
    #4
  5. Ben Wilson

    Ben Wilson Guest

    "David Hilsee" <> wrote:

    > It sounds like you do not merely want to eliminate some code duplication.
    > Now, it sounds like you are trying to do something much harder than that,
    > like implement an object cache where you can clear all of the objects from
    > the cache. That was just a guess. If you explained what your code is

    doing
    > and what you are trying to accomplish, people may be able to help you. Of
    > course, the suggested implementations may require you to rewrite some of

    the
    > code.


    Hi, David:

    I might be overcomplicating the situation with textal explanations. The
    issue is deceptively simple. I'll condense it to a sample that (I hope)
    illustrates it better:


    class myClass
    {
    static int instanceCounter = 0;

    myClass()
    {
    instanceCounter++;
    }

    protected void finalize()
    {
    instanceCounter--;
    }

    }

    There you go - I've got this class, and at runtime I create a couple of
    instances by saying "new myClass()". For argument's sake let's say this was
    part of Process#1 and as a part of Process#1 I want to monitor
    instanceCounter. Later, what I want to do is to start Process#2, #3, #4,
    etc. I want a separate space where the instanceCounter starts off at zero
    and I can create new objects, without any interference from whatever I
    constructed as part of Process#1. Once Process#2 starts I don't care about
    anything that was created in Process#1. Process#1 is over. Forgotten.

    Sure I could manually say "myClass.instanceCounter = 0" however the garbage
    collection of the objects created in the previous Process will interfere
    with this. The old objects of Process#1 will get cleaned up and the
    instanceCounter will go down during Process#2, which is unacceptable.

    Any ideas?

    B.
     
    Ben Wilson, Aug 1, 2004
    #5
  6. Ben Wilson

    David Hilsee Guest

    "Ben Wilson" <> wrote in message
    news:410d628e$0$3965$...
    >
    > "David Hilsee" <> wrote:
    >
    > > It sounds like you do not merely want to eliminate some code

    duplication.
    > > Now, it sounds like you are trying to do something much harder than

    that,
    > > like implement an object cache where you can clear all of the objects

    from
    > > the cache. That was just a guess. If you explained what your code is

    > doing
    > > and what you are trying to accomplish, people may be able to help you.

    Of
    > > course, the suggested implementations may require you to rewrite some of

    > the
    > > code.

    >
    > Hi, David:
    >
    > I might be overcomplicating the situation with textal explanations. The
    > issue is deceptively simple. I'll condense it to a sample that (I hope)
    > illustrates it better:
    >
    >
    > class myClass
    > {
    > static int instanceCounter = 0;
    >
    > myClass()
    > {
    > instanceCounter++;
    > }
    >
    > protected void finalize()
    > {
    > instanceCounter--;
    > }
    >
    > }
    >
    > There you go - I've got this class, and at runtime I create a couple of
    > instances by saying "new myClass()". For argument's sake let's say this

    was
    > part of Process#1 and as a part of Process#1 I want to monitor
    > instanceCounter. Later, what I want to do is to start Process#2, #3, #4,
    > etc. I want a separate space where the instanceCounter starts off at zero
    > and I can create new objects, without any interference from whatever I
    > constructed as part of Process#1. Once Process#2 starts I don't care about
    > anything that was created in Process#1. Process#1 is over. Forgotten.
    >
    > Sure I could manually say "myClass.instanceCounter = 0" however the

    garbage
    > collection of the objects created in the previous Process will interfere
    > with this. The old objects of Process#1 will get cleaned up and the
    > instanceCounter will go down during Process#2, which is unacceptable.
    >
    > Any ideas?


    How about an extra level of indirection?

    private static class Counter {
    public int instances = 0;
    }

    private static Counter globalCounter = new Counter();
    private Counter myCounter = globalCounter;

    public myClass() {
    myCounter.instances++;
    }

    protected void finalize() {
    myCounter.instances--;
    }

    To reset the global counter, just set the global counter (globalCounter =
    new Counter();). Those instances that were created before the counter was
    reset will be referencing the discarded counter and therefore will not
    affect the new counter. If ths will not work, let me know.

    --
    David Hilsee
     
    David Hilsee, Aug 1, 2004
    #6
  7. Ben Wilson wrote:
    > From a design perspective, it feels wrong to have to re-code all of the
    > class-level initialization logic


    From a design perspective, it feels wrong to HAVE a significant amount
    of class-level initializaton logic and use finalize(). To me, anyway.

    Still, I think it might be possible to achieve the behaviour you desire
    if you load all the classes through a custom classloader and when you
    want to "reset" it, you change to a new classloader instance.
     
    Michael Borgwardt, Aug 2, 2004
    #7
  8. Ben Wilson wrote:

    > class myClass
    > {
    > static int instanceCounter = 0;
    >
    > myClass()
    > {
    > instanceCounter++;
    > }
    >
    > protected void finalize()
    > {
    > instanceCounter--;
    > }
    >
    > }
    >
    > There you go - I've got this class, and at runtime I create a couple of
    > instances by saying "new myClass()". For argument's sake let's say this was
    > part of Process#1 and as a part of Process#1 I want to monitor
    > instanceCounter. Later, what I want to do is to start Process#2, #3, #4,
    > etc. I want a separate space where the instanceCounter starts off at zero
    > and I can create new objects, without any interference from whatever I
    > constructed as part of Process#1. Once Process#2 starts I don't care about
    > anything that was created in Process#1. Process#1 is over. Forgotten.


    Hmm, i would do so by adding an explicit dispose() method to your
    Objects. This method signifies that these Objects are no longer "valid".
    Whenever you make a new Object, it leaves one of its References (a
    WeakReference?) in some static collection of the class. Once you call
    initialize, you just dispose all preexisting instances.

    Something like this:

    class myClass {
    static int instances = 0;
    static Collection instance =
    Collections.synchronizedList(new ArrayList);

    boolean disposed = false;

    myClass() {
    instances++;
    instance.add(new WeakReference(this));
    }

    public void finalize(){
    dispose();
    }

    public void dispose(){
    if (!disposed)
    instances--;
    disposed = true;
    }

    static {
    init();
    }

    private static void init() {
    for (Iterator i = instance.iterator; i.hasNext();){
    WeakReference wr = (WeakReference) i.next();
    myClass mc = (myClass) wr.get();
    if (mc != null)
    mc.dispose();
    }
    }
    }
     
    Stefan Schulz, Aug 2, 2004
    #8
  9. Ben Wilson

    Chris Uppal Guest

    Ben Wilson wrote:

    > There you go - I've got this class, and at runtime I create a couple of
    > instances by saying "new myClass()". For argument's sake let's say this
    > was part of Process#1 and as a part of Process#1 I want to monitor
    > instanceCounter. Later, what I want to do is to start Process#2, #3, #4,
    > etc. I want a separate space where the instanceCounter starts off at zero
    > and I can create new objects, without any interference from whatever I
    > constructed as part of Process#1. Once Process#2 starts I don't care about
    > anything that was created in Process#1. Process#1 is over. Forgotten.


    Look for the objects.

    You have a population of instances of myClass, and you have some housekeeping
    data associated with that population. At times to be determined by you, you
    wish to switch to creating a new population and maintaing the housekeeping data
    for the new group of instances without interferance from the old group. Yes ?

    If so, then I would say that it's obvious that you need an object with the
    responsibility for maintaining the housekeeping for a /specific/ population.
    Static data is simply not appropriate for this task (unless you take Gordon's
    suggestion and use classloaders -- in which case you are using the "class" much
    more like a real object).

    So you have a Housekeeper:

    class MyClass
    {
    static class Housekeeper
    {
    private int instances;
    synchronized void addOne() { instances++; }
    synchronized void removeOne() { instances--; }
    }

    static Housekeeper currentHouseKeeper;

    static { resetHousekeeping(); }

    static void resetHousekeeping()
    {
    currentHouseKeeper = new Housekeeper();
    }

    // the housekeeper that knows about /this/ instance
    private final Houskeeper myHousekeeper = currentHouseKeeper;

    MyClass()
    {
    myHouskeeper.addOne();
    }

    protected void finalize()
    {
    myHouskeeper.removeOne();
    }
    }

    This is pretty much the same as David's suggestion. The big difference is that
    I'm claiming that good OO design leads to this solution, rather than presenting
    it as workaround for something that is otherwise needlessly difficult to
    express in Java.

    -- chris
     
    Chris Uppal, Aug 2, 2004
    #9
  10. In article <410d05c6$0$32167$>,
    "Ben Wilson" <> wrote:

    > Now, what if I want to do this with the entire class? And reinitialise all
    > of the static data? By using all of the initializers, instead of going in
    > and manually resetting everything to its original state?


    One reason why you have seen so much pooh-poohing is the inability to
    control when classes are gc'ed and to force a class to be unloaded.

    As time has gone on, the Java community has pretty much concluded that
    finalizers are probably not the best place to release scarce resources.
    (I do wish that Sun had a gc interface or some other means to encourage
    collecting scarce resources so finalizers could be used for this, but
    they do not. Sigh.)

    Thus, there is not a lot of push at Sun to make finalizers a good idea,
    and thus they are not really pushing for class unloads. Sigh.

    Short form: you need to handle static resets yourself. Given that, you
    have to decide how. There are a number of ways, such as lazy init,
    smart factories that track what they have made, or ignoring the issue
    until usage shows what real world problems you will encounter. (For
    example, if your concern is that your statics might blow out memory,
    then you can use a weak hash map to hold them, and a lazy initializer to
    rebuild them. Then, as long as you do not run out of RAM, you do not
    unload anything. Once you do, stuff you do not need will vanish behind
    the scenes.)

    I usually solve this by having my statics created by lazy
    initialization. This usually means that the singleton provider or
    factory has that init logic. If I then want to unload, I have a second
    unloader that does the evil magic, and if I need it, then I usually
    create a thread that does the cleanup every ten seconds or so.

    The unloader is not duplicate code, as that code does not exist anywhere
    else in my class. The factory for each static item is also not
    duplicated code, as it is what is used in the first place.

    Scott
     
    Scott Ellsworth, Aug 2, 2004
    #10
  11. Ben Wilson

    Chris Uppal Guest

    I wrote:

    > class MyClass
    > {
    > static class Housekeeper
    > {
    > private int instances;
    > synchronized void addOne() { instances++; }
    > synchronized void removeOne() { instances--; }
    > }
    >
    > static Housekeeper currentHouseKeeper;


    ....etc...

    I should add that if the housekeeping is really as simple as in this little
    example -- the objects have no need to interact with the housekeeper except at
    birth and death -- then a reference queue may provide a good basis for tracking
    demographics without explicit code in the trackees.

    -- chris
     
    Chris Uppal, Aug 3, 2004
    #11
  12. Hi, Ben,

    On Sun, 1 Aug 2004 21:43:07 +0200
    "Ben Wilson" <> wrote:

    > I could of course keep track of all of the instances in a static
    > ArrayList or so, but that would prevent the normal gc from working so
    > I don't see the solution there.


    Did you have a look at weak references?

    > What I really want to do is to [ctr][alt][del] the whole shabang and
    > let the class initialization run its normal course. I honestly am not
    > sure whether Java allows you to do that in a predictable way.


    May be you could use inner classes. Rough Idea:

    - Move all your instances to the inner class.

    - Make all your static things to instance attributes of the outer class.

    - Create instance methods at the outer class which wrap all constructors
    and static factory methods of your inner class.

    - Then create a single instance of the outer class that is statically
    referenced by the outer class.

    Now, the inner class instances can fiddle with the singleton outer
    object, and foreign code can reach the singleton via the static
    reference.

    For your "reset", simply create a new singleton outer class instance and
    assign it to the static reference.

    I hope it's understandable...

    Markus

    --
    markus schaber | dipl. informatiker
    logi-track ag | rennweg 14-16 | ch 8001 zürich
    phone +41-43-888 62 52 | fax +41-43-888 62 53
    mailto: | www.logi-track.com
     
    Markus Schaber, Aug 3, 2004
    #12
  13. Hi, Ben,

    On Sun, 1 Aug 2004 23:37:18 +0200
    "Ben Wilson" <> wrote:

    > class myClass
    > {
    > static int instanceCounter = 0;
    >
    > myClass()
    > {
    > instanceCounter++;
    > }
    >
    > protected void finalize()
    > {
    > instanceCounter--;
    > }
    >
    > }


    Hmm, try the following (using inner classes):

    public class InstCounter {
    private static InstCounter inst;
    static {
    reset();
    }

    public static InstCounter instance() {
    return inst;
    }

    public static void reset() {
    inst = new InstCounter();
    }

    public myClass getMyClass() {
    return new myClass();
    }

    int instanceCounter = 0;

    class myClass {
    myClass() {
    instanceCounter++;
    }

    protected void finalize() {
    instanceCounter--;
    }
    }
    }

    HTH,
    Markus

    --
    markus schaber | dipl. informatiker
    logi-track ag | rennweg 14-16 | ch 8001 zürich
    phone +41-43-888 62 52 | fax +41-43-888 62 53
    mailto: | www.logi-track.com
     
    Markus Schaber, Aug 3, 2004
    #13
    1. Advertisements

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. Duccio
    Replies:
    0
    Views:
    569
    Duccio
    Feb 25, 2006
  2. AG
    Replies:
    0
    Views:
    596
  3. Kiran Kumar

    aspnet_wp.exe memory consumption

    Kiran Kumar, Jul 15, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    484
    Natty Gur
    Jul 15, 2003
  4. Jenny

    Power Consumption

    Jenny, Jul 17, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    398
    Kevin Spencer
    Jul 17, 2003
  5. Ervin

    Urgent! GDI+ Memory consumption

    Ervin, Sep 15, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    640
    Ervin
    Sep 15, 2003
Loading...

Share This Page