4

Why I am getting a variable output for the following code :

Runtime rt = Runtime.getRuntime();
long x,y;
x = rt.freeMemory();
char z[] = new char[Index];
y = rt.freeMemory();

System.out.println("Difference = " + (x-y))

Output is = Zero for lesser Value of Index(<10000) but for values >=100000 value is 200016.For every Zero addition it becomes 2000016.

How is it possible. [edited]My aim is to find the size of the Data Object(used in the code- like here I have used Char z[] of Index Size) in the memory.

skaffman
  • 398,947
  • 96
  • 818
  • 769
Raulp
  • 7,758
  • 20
  • 93
  • 155
  • 2
    `freeMemory()` isn't meant to be precise like that, and doesn't take into account GC and the like. If you need to measure memory consumption, use a tool like [MemoryMeasurer](http://code.google.com/p/memory-measurer/). – Louis Wasserman May 08 '12 at 17:56
  • 3
    The JVM is a complicated beast. For all we know, it may be optimizing away the entire `char z[] = new char[Index];` because it's not actually used elsewhere. – Matt Ball May 08 '12 at 17:57
  • So the result of rt.freeMemory() can never be trusted?Can it be?What is the minimum least count(the minimum value of memory consumption) i can check upto and by which method call? – Raulp May 08 '12 at 17:59
  • I wouldn't ever depend on it in your program. Its accuracy will vary widely even within runs of the same program, let alone with JVM configuration options. It'd help if you told us what you actually want to do with this data. – Louis Wasserman May 08 '12 at 18:01
  • @LouisWasserman : edited with my intent in the question! – Raulp May 08 '12 at 18:06
  • 3
    If your goal is just to do memory measurement for your program in advance, then use the MemoryMeasurer tool I linked above, but there's no reliable, fast way to measure memory consumption of objects at runtime in the middle of production code. – Louis Wasserman May 08 '12 at 18:07

2 Answers2

2

Your assumption seems to be that if you have n bytes of free memory, and allocate m bytes, then you will have n-m bytes of free memory afterwards.

This is a rational hypothesis, but it is false in the presence of asynchronous garbage collectors that will or will not do memory compaction jsut as they see fit.

And even if you spend years to study the behaviour of a certain JVM and accumulated deep wisdom and knowledge that allowed you to predict the effect of allocation on the result of freeMemory(), this knowledge may suddenly become worthless as you switch to another JVM or only update your current one.

Hence, trust us elder ones and look at Runtime.freeMemory() as a kind of a funny random number generator.

Ingo
  • 36,037
  • 5
  • 53
  • 100
0

I write System.gc() and you can see the difference.

    Runtime rt = Runtime.getRuntime();
    long x,y;
    System.gc();
    x = rt.freeMemory();
    char z[] = new char[1000];
    y = rt.freeMemory();

    System.out.println("X = " + (x));
    System.out.println("Y = " + (y));
    System.out.println("Difference = " + (x-y));

Output

X = 16179672
Y = 16085904
Difference = 93768
Bhavik Ambani
  • 6,557
  • 14
  • 55
  • 86
  • 4
    `System.gc()` doesn't guarantee garbage-collection -- it just "encourages" GC to happen. It's not good to depend on it, and it certainly won't get you really accurate results. – Louis Wasserman May 08 '12 at 18:02
  • But you can see the difference. I achive the motive and I also tried more then 50 times executing the code and then I posted the answer. – Bhavik Ambani May 08 '12 at 18:03
  • 3
    You got _lucky._ You _can't_ depend on GC getting you accurate data. In any event, `char[]` arrays take 12 bytes of overhead and then 2 bytes per `char`, rounded up to a multiple of 8. Your data suggests that other stuff is going on around the GC. You _cannot_ get accurate results with this technique. – Louis Wasserman May 08 '12 at 18:05
  • @LouisWasserman That is currect that you can not get the accurate result. But the problem of getting `0` as a result is resolved that is my point. – Bhavik Ambani May 08 '12 at 18:06
  • 2
    It won't always be resolved. `System.gc()` won't always trigger garbage collection -- it's just a suggestion to the JVM. – Louis Wasserman May 08 '12 at 18:08
  • I thought System.gc() starts with the finalize on all objects? Not sure though – Venki May 08 '12 at 18:11
  • @Morpheus Thats wrong understanding of` System.gc()` we can use this any time. – Bhavik Ambani May 08 '12 at 18:13
  • This clarified me http://stackoverflow.com/questions/2414105/why-is-it-a-bad-practice-to-call-system-gc – Venki May 08 '12 at 18:16