Reuse objects
"Martin Carlberg" <[email protected]> Wed, 24 Sep 2003 10:28:10 +0200
| Newsgroups | gmane.comp.web.webobjects.eof,gmane.comp.web.webobjects.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello!
I have written some code to reuse attribute objects in
enterprise objects. I have an application that caches a
lot of information from the database in memory (around
500MB). When I analysed it, I could see many attributes
that contained the same thing. I wanted to do something
about it.
In many sessions at WWDC over the years I have been told
not to reuse objects with pools or other implementations.
Just make new objects and the Java VM will take care of
it. Now I did a pool anyway just for testing and I found
out that I saved 12% of memory and the code was around 2%
faster. Yes it was faster because I don't need to use the
"equals" method. I could just compare if two objects are
the same.
Now this is probably not for the average application but
it works in this one. Has someone else experiences on
this. Is this the way to go? Is it possible to improve my
implementation? Is it safe to deploy? I would like to get
any thoughts or feedback on this.
I have supplied some code. The ReuseObject class handles
the pool of objects to reuse. The Application class adds
itself as a delegate to grab the rows from the database. I
also made sure that all the set methods in the EO classes
are modified like the example at the bottom.
I'm using WebObjects 5.1 on Windows 2000.
Best regards,
- Martin Carlberg
- System Developer
- Oops AB
- http://oops.se
import java.lang.ref.*;
import java.util.*;
import com.webobjects.foundation.*;
public class ReuseObject {
private static WeakHashMap reusableObjects = new
WeakHashMap(3000);
public static Object reuseObjectForObject(Object
anObject) {
WeakReference cachedObjectRef =
(WeakReference)reusableObjects.get(anObject);
if (cachedObjectRef != null) {
Object cachedObject = cachedObjectRef.get();
if (cachedObject != null) {
return cachedObject;
}
}
reusableObjects.put(anObject, new
WeakReference(anObject));
return anObject;
}
public static void
reuseObjectsInDictionary(NSMutableDictionary dict) {
Enumeration enum = dict.keyEnumerator();
while (enum.hasMoreElements()) {
Object key = enum.nextElement();
Object value = dict.objectForKey(key);
Object reuseObject = reuseObjectForObject(value);
if (reuseObject != value) {
dict.setObjectForKey(reuseObject, key);
}
}
}
}
public class Application extends WOApplication {
public Application() {
super();
EOAdaptorContext.setDefaultDelegate(this);
}
public void adaptorChannelDidFetchRow(Object channel,
NSMutableDictionary row) {
ReuseObject.reuseObjectsInDictionary(row);
}
}
public class DatabaseObject extends EOGenericRecord {
public void setName(String value) {
takeStoredValueForKey(ReuseObject.reuseObjectForObject(value),
"name");
}
}