3

Is there a way to predict how much memory my Java program is going to take? I come from a C++ background where I implemented methods such as "size_in_bytes()" on classes and I could fairly accurately predict the runtime memory footprint of my app. Now I'm in a Java world, and that is not so easy... There are references, pools, immutable objects that are shared... but I'd still like to be able to predict my memory footprint before I look at the process size in top.

2
  • 1
    MemoryMeasurer is a pretty straightforward library to use to measure entire object graphs. Commented Aug 17, 2012 at 17:19
  • Note that, as I stated in my answer below, working set is essentially equal to GC heap size + JVM overhead, regardless of how many objects of whatever size you have. Commented Aug 17, 2012 at 18:32

4 Answers 4

2

You can inspect the size of objects if you use the instrumentation API. It is a bit tricky to use -- it requires a "premain" method and extra VM parameters -- but there are plenty of examples on the web. "java instrumentation size" should find you these.

Note that the default methods will only give you a shallow size. And unless you avoid any object construction outside of the constructor (which is next to impossible), there will be dead objects around waiting to be garbage collected.

But in general, you could use these to estimate the memory requirements of your application, if you have a good control on the amount of objects generated.

Sign up to request clarification or add additional context in comments.

1 Comment

That is great! It has a "getObjectSize" method! Just what I was looking for.
1

You can't predict the amount of memory a program is going to take. However, you can predict how much an object will take. Edit it turns out I'm almost completely wrong, this document describes the memory usage of objects better: http://www.javamex.com/tutorials/memory/object_memory_usage.shtml

5 Comments

Object references probably don't take only 32 bits on a 64-bit JVM. Also, I think the per-object overhead could be different between JVM implementations.
@MikeDaniels depens, I think that Oracle Java currently uses some method of compression on the references - at least that's what I remember seeing somewhere someplace.
64 bit VMs often run in "compressed pointer" mode, where the pointers still are 32 bit only. But yes, in general there could be differences. See my reply wrt instrumentation API.
Google "Java instrumentation API". It seems there is a way to get an estimate.
@owlstead (and Anony-Mousse) Thanks guys, I didn't know about compressed pointers.
1

In general, you can predict fairly closely what a given object will require. There's some overhead that is relatively fixed, plus the instance fields in the object, plus a modest amount of padding. But then object size is rounded up to at least (on most JVMs) a 16-byte boundary, and some JVMs round up some object sizes to larger boundaries (to allow the use of standard sized pre-allocated object frames). But all this is relatively fixed for a given JVM.

What varies, of course, is the overhead required for garbage collection. A naive garbage collector requires 100% overhead (at least one free byte for every allocated byte), though certain varieties of "generational" collectors can improve on this to a degree. But how much space is required for GC is highly dependent on the workload (on most JVMs).

The other problem is that when you're running at a relatively low level of allocation (where you're only using maybe 10% of max available heap) then garbage will accumulate. It isn't actively referenced, but the bits of garbage are interspersed with your active objects, so it takes up working set. As a result, your working set tends to be roughly equal to your current overall garbage-collected heap size (plus other system overhead).

You can, of course, "throttle" the heap size so that you run at a higher % utilization, but that increases the frequency of garbage collection (and the overall cost of GC to a lesser degree).

Comments

0

You can use profilers to understand the constant set of objects that are always in memory. Then you should execute all the code paths to check for memory leaks. JProfiler is a good one to start with.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.