SpatialPool?

Hehe didn't mean to start a religious war here :slight_smile: I'd forgotten about the dependencies, which is really a PITA…

Anyway, I'm really eager for your ObjectPool implementation, as it'll be really useful for my project. So good luck with that :wink:

…remember how I said I had done it the way lazlohf had suggested?



…I just remembered where:



http://captiveimagination.com/svn/public/jcommon/trunk/src/org/jcommon/util/ObjectPool.java



It’s really sad when I forget I’ve already written something and go write it again…especially when I don’t do as good of a job the second time around.  :stuck_out_tongue:

…I wrote it in September of last year.



Man…there's something wrong with me. 

Okay, so the question is, does this really belong in jME?  Like we've already discussed, there's nothing that makes it inherently "jME-ish", so should I just pull out what I've written and some people can go down the heretical Apache Commons trail, some can go down their own trail, and then the others can choose the path to righteousness with jCommon? :wink:

"lazlohf" wrote:
make sure to avoid a .size() call, that one could be a big hit.

public T get() {
      if (available.size() == 0) {
         try {
            return createInstance();
         } catch(Exception exc) {}
      }
      return available.poll();
   }



I'm just the messenger here :)

Edit: a simple optimization ?


public T get() {
        try {
                T o = available.poll();
                if (o == null) {
              o = createInstance();
           }
           return o;
        }
        catch (Exception exc) {}
}

I was just going to ask why SpatialPool worked how it did, because I've written something much more like ObjectPool for bullets and stuff in my game. I was worried SpatialPool had some hidden benefit because it hurts my head how it works :slight_smile:



If SpatialPool stays, can it be changed to work the way ObjectPool does?



Just one note on life cycle - if objects can be reused, they can be much easier to use if they have a "die" method that causes them to reset themselves and return themselves to their own pool. That way you don't need to keep a reference to the pool something came from wherever you might kill it. That works well for bullets etc. since there may be a few ways they can be got rid of when they hit something, but they can all just tell the bullet to "die" then forget about it. Not ever calling the pool's "return" method is also good since there is less chance of returning something that shouldn't be returned, or returning something to the wrong pool - when things return themselves they are more likely to do it correctly.



Can the ObjectPool just call poll() and make a new instance if the return is null?

darkfrog said:

....remember how I said I had done it the way lazlohf had suggested?

.....I just remembered where:

http://captiveimagination.com/svn/public/jcommon/trunk/src/org/jcommon/util/ObjectPool.java

It's really sad when I forget I've already written something and go write it again....especially when I don't do as good of a job the second time around.  :P


I like having a SpatialGenerator-type interface for instance creation rather than the ObjectPool.createInstance way, makes it nicer if there's no non-param constructor or if I always want to create an object the set up a few items (bounding box or something I guess). See, so the second one does have an improvement IMHO :wink:

darkfrog said:

Okay, so the question is, does this really belong in jME?  Like we've already discussed, there's nothing that makes it inherently "jME-ish", so should I just pull out what I've written and some people can go down the heretical Apache Commons trail, some can go down their own trail, and then the others can choose the path to righteousness with jCommon? ;)


The com.jme.util package makes sense to me. What do the other JME devs/committers do in their games to manage bullets or other models they create or re-use often?

shingoki said:

Just one note on life cycle - if objects can be reused, they can be much easier to use if they have a "die" method that causes them to reset themselves and return themselves to their own pool. That way you don't need to keep a reference to the pool something came from wherever you might kill it. That works well for bullets etc. since there may be a few ways they can be got rid of when they hit something, but they can all just tell the bullet to "die" then forget about it. Not ever calling the pool's "return" method is also good since there is less chance of returning something that shouldn't be returned, or returning something to the wrong pool - when things return themselves they are more likely to do it correctly.


Yep, no "close" or "die" method to latch on to that I know of  :|  I can't really give an opinion on which way I like until I get to a point where I need object pools and try them out. My first guess would be maintaining a pool singleton in the class I want to pool and accessing it internally via a "die" method, similar to a previous post I did about Vector3f. So if I had a Bullet class, I'd have a static getInstance() and privatize the constructor to guarantee objects are retrieved from the cache, and a Bullet.done/die/close/release method that simply added "this" back into the private static pool singleton. Yeah, you have to modify each pooled class this way but I find it to be a bit cleaner than having external pools and the issues you mentioned about knowing which pool gets an object back.

So would you guys like SpatialPool to be removed or should I pull in the code from ObjectPool and add features to make it more useful for game development?



I'm not so sure about the whole "return itself to the queue".  In my opinion you can easily provide some access in your own game to handle this if it is desired.  Simply passing the ObjectPool to the object in the constructor or on a setter method after instantiation and then invoking the ObjectPool's put method to put it back would probably be identical to what you're wanting but wouldn't require any changes to ObjectPool.

darkfrog said:

So would you guys like SpatialPool to be removed or should I pull in the code from ObjectPool and add features to make it more useful for game development?

I'm not so sure about the whole "return itself to the queue".  In my opinion you can easily provide some access in your own game to handle this if it is desired.  Simply passing the ObjectPool to the object in the constructor or on a setter method after instantiation and then invoking the ObjectPool's put method to put it back would probably be identical to what you're wanting but wouldn't require any changes to ObjectPool.


I'd like ObjectPool with ISpatialGenerator  }:-@  So I guess SpatialPool using a Queue instead of List, and renamed to ObjectPool? I also wouldn't need the inUse List, but a reference counter would be good for tracing possible leaks.

Passing an ObjectPool into the constructor or using it as a singleton within the class shouldn't impact ObjectPool's interface or internals at all. We can use it my, yours, Shingoki's, or many other ways.

I also see llama's WeakReference pool being useful, I would just like to test it out on a few different VM's and OS's to see how quickly unref'd objects are flagged. Honestly, I haven't really used WeakReference, wouldn't it add a decent bit of code to check if weakRef.get() returns null when you access the object? If it does you'd have to go back to the pool and get a new one? I guess a simple util method could handle all that. AFAIK the VM can kill a weak reference even if it has been used recently, especially when available memory is running low (like a soft reference).

Yup sorry I wasn't very clear - the "die" thing doesn't need any changes to ObjectPool, it was just something I found useful when using pools :wink: ObjectPool looks like it does everything mine does, but is threadsafe and probably much more efficient.

We definitely need to do some testing with References before deciding if it's the right way to go for this.  I'm concerned it could potentially be minutes after something is finished being used before it is able to be reclaimed into the pool this route.

Uhm, I think you're confusing soft references with weak references or you are confusing reachability with reclaiming or finalizing.



Weak references are added to their ReferenceQueue when the object they hold becomes reachable through the weak references only. Reference counting is typically done at the moment that you set/unset references, so it would normally almost instantanious. Only the notification itself is asynch afaik (and poll based, even).



I'll admit I'm no expert on Sun's VM implementation, maybe they have some fancy multithreading scheme for reference counting, but that should still shouldn't slow the process down more than a few ms at most. Finalization (the actual destruction of an object) can take a lot longer, it's queued and what not. but… we're not finalizing any object here. We're putting them back in the pool. Only the WeakReference objects have to be reclaimed eventually.



edit: hmm… seems Sun's implementation is a bit weirder than I thought… it looks like it indeed does have some weird scheme, where it seems to schedule reference counting, and it can hang for long times… as long as the rest of your program is completly idle.

Hmmm…well, based on that information I think it's not an unreasonable requirement to have people manually release an object when they're done with it.



Game development is ultimately about performance and that should be the most performant way to do this, right?  I'm going to go ahead and merge my work on SpatialPool and ObjectPool and get it together into jME.



@llama, if you still want the WeakReference system I can go ahead and add an option for that?

Okay, just checked in my new version of ObjectPool that should now have the best of both systems with a few additional features added in. :wink:

darkfrog said:

Okay, just checked in my new version of ObjectPool that should now have the best of both systems with a few additional features added in. ;)


Cool, generator and Class.newInstance support :) I can see the enable/disable being useful also for more complex objects. I haven't tried it out yet but the code looks good to me.
llama said:

Uhm, I think you're confusing soft references with weak references or you are confusing reachability with reclaiming or finalizing.

...


Yep, you're right! What I was talking about doesn't apply with your use of a weak reference queue for caching.

llama said:

...

edit: hmm.. seems Sun's implementation is a bit weirder than I thought.. it looks like it indeed does have some weird scheme, where it seems to schedule reference counting, and it *can* hang for long times... as long as the rest of your program is completly idle.


That's what I worried about when I looked through the javadocs for WeakReference, it defines a contract for use but leaves a lot open in terms of implementation (reminds me of so many Sun interfaces  ;) ). Makes sense so very creative optimizations can be used. If anyone happens to implement this type of pool, I'd be very interested in hearing how it works out. I'll be sure to post results if I give it a shot.

I heard sometimes the term "reference counting" in this thread. Java GC definitely doesn't work that way (else mutual depending objects would never GCed)

Landei said:

I heard sometimes the term "reference counting" in this thread. Java GC definitely doesn't work that way (else mutual depending objects would never GCed)


I think only once (by me), and ok, that's true. Tracing is quite different from reference counting, I already knew that, however I didn't know how different. Indeed tracing does not seem to be triggered by removing a reference.