Results 1 to 5 of 5
- 06-02-2011, 01:57 AM #1
Per-class memory and performance overhead?
I read this book a long time ago, and it's stuck with me that there's significant overhead for each class that's loaded. But I know that many of the recommendations in that book are now obsolete, and what was significant then may not be significant now.
I'm using Sun's CodeModel API to generate a client-server message library for a game. It would be easy to generate a subclass for each message type, making the library more type-safe and allowing method overloading. But what kind of impact would dozens (possibly hundreds) of small classes have on memory use and startup time?
If nobody knows, I might just have to run some experiments...
Get in the habit of using standard Java naming conventions!
- 06-02-2011, 03:40 AM #2
Did someone delete a comment?
To answer your question... yes, there is a is-a relationship.
If my generic Message class were an interface, it would look like this:
If I extended it for every message type, I could do away with those public getters (and the fragility of needing to pass the right key for every value) and replace them with meaningful names, e.g., Message.getIntArray("warps") becomes SectorData.getWarps().Java Code:public interface Message { public long getTimestamp(); public MessageType getType(); // MessageType is an enum void setParam(String key, int value); public int getInt(String key); // a bunch more package-private setters and public getters }
Edit: I've been thinking in terms of the representation of a Message. In that sense, a SectorData definitely is-a Message; it ought to be able to represent itself in forms suitable for logging, sending to a client, etc., just like a generic Message. But if I were to start extending Message, I could build more meaningful is-a relationships, like LocalSectorData is-a SectorData.
There are so many advantages to extending my generic Message, I'm thinking I should probably just do it. Performance might be an issue, but I'll never know unless I try it.Last edited by kjkrum; 06-02-2011 at 04:00 AM.
Get in the habit of using standard Java naming conventions!
- 06-02-2011, 05:47 AM #3
Okay, so I ran some tests. Perhaps someone can comment on the validity of this experiment.
I scripted the creation of 1000 empty classes (Class0 ... Class999). Then I scripted the creation of three test programs that reference 10, 100, or 1000 of those classes. Here's the 10 version:
The time to load the classes was pretty consistent between several runs. I inspected the JVM's memory usage in top while each program was "paused" (chewing on my CPU.) Here are the results:Java Code:package krum.manyclasses; public class Load10 { public static void main(String[] args) { long started = System.currentTimeMillis(); Class clazz = null; clazz = Class0.class; clazz = Class1.class; clazz = Class2.class; clazz = Class3.class; clazz = Class4.class; clazz = Class5.class; clazz = Class6.class; clazz = Class7.class; clazz = Class8.class; clazz = Class9.class; System.out.println("Loaded 10 classes in " + (System.currentTimeMillis() - started) + "ms"); System.out.println("Pausing for dramatic effect."); while(true) { } } }
10 classes: ~7ms, 1.7% of ~768mb
100 classes: ~122ms, 2.2%
1000 classes: ~660ms, 2.8%
This on a netbook with an AMD V105 CPU and a 5400 RPM platter drive. It appears my concerns were unfounded.
Edit: Would the class definitions be getting GCed? I don't think so... but even if they are, I'm reassured about potential performance issues.Last edited by kjkrum; 06-02-2011 at 05:53 AM.
Get in the habit of using standard Java naming conventions!
- 06-02-2011, 08:35 AM #4
I changed the test programs to use Class.forName(), and got almost identical results.
I'll stop talking to myself now.Java Code:package krum.manyclasses; public class Load10 { public static void main(String[] args) { long started = System.currentTimeMillis(); try { Class class0 = Class.forName("krum.manyclasses.Class0"); Class class1 = Class.forName("krum.manyclasses.Class1"); Class class2 = Class.forName("krum.manyclasses.Class2"); Class class3 = Class.forName("krum.manyclasses.Class3"); Class class4 = Class.forName("krum.manyclasses.Class4"); Class class5 = Class.forName("krum.manyclasses.Class5"); Class class6 = Class.forName("krum.manyclasses.Class6"); Class class7 = Class.forName("krum.manyclasses.Class7"); Class class8 = Class.forName("krum.manyclasses.Class8"); Class class9 = Class.forName("krum.manyclasses.Class9"); System.out.println("Loaded 10 classes in " + (System.currentTimeMillis() - started) + "ms"); System.out.println("Pausing for dramatic effect."); while(true) { Thread.sleep(100); } } catch(Exception e) { e.printStackTrace(); } } }
Get in the habit of using standard Java naming conventions!
- 06-02-2011, 09:44 AM #5
Moderator
- Join Date
- Apr 2009
- Posts
- 10,460
- Rep Power
- 16
Similar Threads
-
Assigning an existing class to a new variable (memory issue)
By chardsigkit in forum New To JavaReplies: 8Last Post: 03-04-2011, 01:50 PM -
GC Overhead limit exceeded error when reading a text file
By collegian in forum New To JavaReplies: 0Last Post: 10-20-2010, 03:47 PM -
Runtime overhead of Class inheritence level?
By devaru2003 in forum Advanced JavaReplies: 5Last Post: 07-14-2010, 09:51 AM -
Scanner Class Performance?
By jazz2k8 in forum New To JavaReplies: 1Last Post: 05-14-2008, 02:42 AM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks