• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Object size in memory?

 
Ranch Hand
Posts: 532
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi all:
I have built a utility class to estimate the object size in memory, if the object has no-argument constructor. I built my class following the direction mentioned on http://www.javapractices.com/Topic83.cjp and it follows the style used by Java Platform Performance, by Wilson and Kesselman.
The result was as follows:
java.util.ArrayList = 78 bytes
java.util.Vector = 78 bytes
java.lang.String = 48 bytes
is it possible? how can an object of a class that contains over 15 methods, variables, and constructor be only of the size 80 bytes?
I don't understand it?
any explination is greatly appreciated.
thanks
 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What that code is actually measuring is the size the object instance
takes up in memory, which is pretty close to the sum of all it's attributes + 8 bytes (I think) for the identifier.
For an empty ArrayList, there is only a reference to an empty array in it, plus all of it's parent classes attributes.
I'm actually thinking it's a little large.
What you want to measure is the size of the Class, which is loaded up once for every object, when the first class is instantiated.
ie at this line

You won't be able to load it 100 times and get the average like the code does, because it'll only ever load once, no matter how many times you call that line.
[ April 23, 2004: Message edited by: Mike Fuellbrandt ]
 
Hanna Habashy
Ranch Hand
Posts: 532
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mike:
thank you for your reply. What I understand now is that the class size is much larger than the object size. an object of a class is only reference its own attrbutes and its inhereted attributes. How about the method? public and private? does it take any space in the object memory? With my understanding, an object of a class that doesn't have any attributes should be very small, no matter how many methods it contains.
Am I correct??
One more question. How can I measure the class size in memory?
thanks
 
Mike Fuellbrandt
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Methods, public or private, should have no effect on the object instances memory, but I don't have perfect knowledge on this.
As for measuring the Class size, it's tricky.
You could attempt to measure memory use before and after the line:
class.forName(className);
However, you cannot be certain that that measurement is accurate. This is why the memory measurement code adds 100 instances and gcs all the time and takes the average for an estimate. This approach won't work for the Class, because it can only be loaded once (I think...).

Something to try (I haven't and don't know which would work):
- You could attempt to load multiple copies of the reflected Class Object. Whether the size of the Class object reflects the size of the actual class is not known to me, so <shrug>.
 
Hanna Habashy
Ranch Hand
Posts: 532
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mike:
Thanks again for you reply. I have tried Class.forName() and I got a bizar result. Her is the code:
collectGarbage();
collectGarbage();
long startMemoryUse = getUsedMemory();
Class.forName(aClass);
long endMemoryUse = getUsedMemory();
long result = endMemoryUse - startMemoryUse;
When I load one of my own classes, I got the size around 160 bytes. If I tried to load any class from the jave library, I got -64. I don't know where is the number -64 come from. I tried it with String, ArrayList, and Vector.
Any ideas.
 
Mike Fuellbrandt
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Like I said, you can't get an accurate number.
What is likely happening is some stuff (unrelated to your app) is getting garbage collected.
There's probably no reliable way to accomplish this.
Wait, I've just had a thought... The class size in memory probably corresponds to the byte-code .class file.
Can we get some confirmation from someone who knows better?
 
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

collectGarbage();
collectGarbage();
long startMemoryUse = getUsedMemory();
Class.forName(aClass);
long endMemoryUse = getUsedMemory();
long result = endMemoryUse - startMemoryUse;
When I load one of my own classes, I got the size around 160 bytes. If I tried to load any class from the jave library, I got -64. I don't know where is the number -64 come from. I tried it with String, ArrayList, and Vector.
Any ideas.

Four things:
1. It's often neccessary to invoke gc() several time before the full GC kicks in. You can monitor that condition by looking at the verbose output -- start JVM with the -verbose:gc parameter.
2. In your pseudocode, you measure the "endMemoryUse" after loading the class. There is a step missing -- you must garbage collect before taking the "endMemoryUse".
3. When measuring memory, explicitely specify the min and max size of the heap with the same value, using -Xms and -Xmx parameters. Otherwise, the JM may reserve additional memory on the fly and your measurements will be rendered useless.
4. Instead of trying to measure the size of a single object, measure the size of the 10,000 objects, then divide by that number to come up with the average.
[ April 25, 2004: Message edited by: Eugene Kononov ]
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Hanna Habashy:
If I tried to load any class from the jave library, I got -64. I don't know where is the number -64 come from. I tried it with String, ArrayList, and Vector.


It's quite likely that those classes are already loaded, because they are used by some system code.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mike Fuellbrandt:
For an empty ArrayList, there is only a reference to an empty array in it, plus all of it's parent classes attributes.


The array will actually not be empty. Take a look at the ArrayList constructor.
Additionally, every object needs to hold some information about which class it belongs to.
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is some code to calculate the size of an ArrayList in memory. Although the method is somewhat different than used in the original post, the results are consistent, -- the output of my code is "79 bytes", while the original code estimates it at 78 bytes.
 
Ranch Hand
Posts: 5093
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
An empty ArrayList would have AT LEAST a reference to an array of 10 Objects plus an int giving its size.
That's effectively 11 32-bit Object references for a total of 44 bytes.
Add 4 bytes for the int and you have 48 bytes.
Then there's a long (8 bytes) for the version information.
Now we're up to 56 bytes.
Class information would add some more.
 
Hanna Habashy
Ranch Hand
Posts: 532
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you all for the valuable information. I really appreciate it.
another question: is there any way to get a class size in memory?
thanks
 
Jeroen Wenting
Ranch Hand
Posts: 5093
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
unlikely. It's pretty irrelevant information unless you're working on resource starved systems (think J2ME) in which case you'll find out quickly enough when you're in trouble
 
Hanna Habashy
Ranch Hand
Posts: 532
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jeroen:
Why it is irrelevant information? Can you explain. I know java objects lives on the heap. Where does the classes the parents of those objects live?
thanks
 
Jeroen Wenting
Ranch Hand
Posts: 5093
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You have no influence over it anyway so why bother?
You have to also make a BIG distinction here. Your class instances live on the internal heap of the JVM, the classes themselves could live anywhere depending on JVM implementation.
In the memory of your computer both could live on the heap but don't have to, depending on hardware and OS implementation.
In general: when using Java let the JVM worry about memory management.
That doesn't mean that you shouldn't do things like minimising object instantiation and minimising the amount of data you declare (so don't use a long when an int would suffice for example), but you should not try to outsmart the JVM and implement your own memory management code.
 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is important under the following circumstance- a very very large number of object are anticipated, say a million. The design of the class of these objects then becomes very important. Making them too heavyweight with many ArrayLists may cut the number of objects the VM can handle by 1/10th or more. However, sparing the member of type ArrayList at every opportunity may create a speed issue with respect to searching (for items that would naturally be in those ArrayLists). Worse, either performance issue might not surface until a customer uses the software in an unanticipated field requiring unanticipated performance and or memory demands.

A good thread here. It sees as though you ought to be able to get an upper limit by tracing the graph of the class of ArrayList the way a GC would and just totaling up everything you encounter.
 
Rancher
Posts: 13459
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"software visualization",
Welcome to the JavaRanch.

We're a friendly group, but we do require members to have valid display names.

Display names must be two words: your first name, a space, then your last name. Fictitious names are not allowed.

Please edit your profile and correct your display name since accounts with display names get deleted, often without warning

thanks,
Dave
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic