• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Declaration difference

 
Arijit Ghosh
Ranch Hand
Posts: 174
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the difference between the following from the point of view of memory usage, memory occupancy, faster access etc... Which one uses more memory space ? Internally how are they accessed ?
char c = 'x';
Character q = new Character(c);
AND
Character a = new Character('x');
 
Dinesh Kumar
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Arijit,
I think the first method would obviously take more memory as it would need to maintain an additional reference to the variable value 'x' in the symbol table (or whatever Java's equivalent is).
Also, the object with the variable passed as parameter in the constructor would keep a copy of the value 'x' and not a reference to the location where 'x' is stored.
So whether you pass 'x' as a literal to the constructor or as a variable, the object is going to take up the same space and spend the same time accessing that value.
I hope I am correct. I just have discussed it the way I think it should be.
Thanks,
Dinesh
 
Valentin Crettaz
Gold Digger
Sheriff
Posts: 7610
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually both versions should use the same amount of memory on 32 architectures since an int is stored using 32 bits, and 32-bits arch use the same amount of bits for storing addresses.
The following program shows the concept:

Output of //1:
Before:1870064
After:1869080
Memory Used = 1870064 - 1869080 = 984 bytes
Output of //2
Before:1870072
After:1869088
Memory Used = 1870072 - 1869088 = 984 bytes
[ October 30, 2002: Message edited by: Valentin Crettaz ]
 
Arijit Ghosh
Ranch Hand
Posts: 174
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But how is it that in one case you are declaring a new variable "c" while in the other case there is nothing to worry about that ?
In both the cases, literal 'x' is stored and memory is used up for that.
In first case, you have a variable "c" which occupies some memory location. (Isn't it ? or am I wrong ?) In the 2nd case, memory requirements should be much less as there is no such variable as "c".
Am I right ?
But then how is Valentin's code explained ?
Regards,
Arijit
 
Valentin Crettaz
Gold Digger
Sheriff
Posts: 7610
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Declaring a local variable for temporarly storing the character literal 'x' or putting 'x' directly into the constructor must have the same effect, that is, 'x' must be put on the operand stack and use some memory.
In the first case, 'x' is explicitely referencable through the variable c, that is, what gets passed to the constructor is a reference to c, while in the second case, 'x' is not referencable once the object creation expression has been executed. But the effect is the same in both cases, 'x' is pushed on the operand stack and used by the constructor, thus the same amount of memory used.
Moreover, on the stack there are only two things, the character literal 'x' (and the reference to it in the first case), and the reference to the Character object (which is created on the heap)
[ October 30, 2002: Message edited by: Valentin Crettaz ]
 
Arijit Ghosh
Ranch Hand
Posts: 174
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Moreover, on the stack there are only two things, the character literal 'x' (and the reference to it in the first
case), and the reference to the Character object (which is created on the heap)

If that is so, then in the first case, we have literal 'x', its reference "c" and the reference to the Character object
while in the 2nd case, we have literal 'x' and the reference to the Character object
So should not the memory occupied be less in the 2nd case ?
Regards,
Arijit
 
Valentin Crettaz
Gold Digger
Sheriff
Posts: 7610
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No because in the second case, the reference to 'x' is implicit. It's there, it exists, you just don't see it. If I get the time, I'll decompile both versions of the code and show you what I mean.
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The first method produces the following javap output

bipush 120
invokespecial #13 Method java.lang.Character(char)

here the value of x is passed directly to the constructor without being stored in any local variable.
For the second method:

bipush 120
istore_2
new #12 Class java.lang.Character
dup
iload_2
invokespecial #13 Method java.lang.Character(char)

X is stored in local variable 2 and later passed to the constructor. Thus I would say that during the execution of main the java stack for the second method holds a local variable (4 bytes for any int type or below) that is not present with the first method. However this difference in size is not made evident by freeMemory()
[ October 30, 2002: Message edited by: Jose Botella ]
 
Arijit Ghosh
Ranch Hand
Posts: 174
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Understood Valentin's explanation.
Confused about Jose's explanation ? I guess, what she meant for the first method was for the second method ( directly passing to the Constructor) and vice-versa. Is it ?
So does it mean that memory requirements in the 2 cases are not same ??
[ October 30, 2002: Message edited by: Arijit Ghosh ]
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is a local variable "c" that must be stored in the java stack that does not appear in the other method. This is only a difference of 4 bytes for the size of the stack.
 
Arijit Ghosh
Ranch Hand
Posts: 174
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is right, Jose. But then how do you explain this -->

as mentioned by Valentin, that the output is same for both the cases.
Is it that internally, JAVA creates a reference and to which we don't have access ??
Regards,
Arijit
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you asking regarding the "x" in "Character a = new Character('x');" ? No, the compiler will not create a local variable only for this use. The parameter is passed as an int with the bytecodes "bipush 120"
The API for freeMemory says that it returns an aproximation for the memory where objects are created.
It seems to me that the stacks are not taken from the heap. That is, I think freeMemory is not able to see variations due to the number of "primitive" local variables.
[ November 01, 2002: Message edited by: Jose Botella ]
 
Alfred Kemety
Ranch Hand
Posts: 279
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
silly question what's a heap?
 
Ron Newman
Ranch Hand
Posts: 1056
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A "heap" is an area of memory holding objects whose lifetimes are not tied to the scope of a local variable in a function.
In Java, all Objects live in the heap.
In C or C++, malloc() allocates memory in the heap, and free() frees it.
 
Don Bosco
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
FYI,
All objects are stored on Heap.
All Local variables and formal parameters are stored on Stack.
and Where are the static variables stored?
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
static fields that are not compile time constants are stored in the "method area" of the JVM. This is where all the information for a class is loaded, especially the method's code.
compile constants are stored in the constant pool of the class, or are replaced by its value if it is feasible doing so.
An example : the bytecodes like "bipush 120" could be used for compiler whenever a field like "final char c = 'x';" is accessed. Doing so the compiler avoids accessing a field, which is more expensive that just using a value that is known not to change.
This code shows that the compile constant fields are retrieved from the constant pool if no "bipush", "sipush" bytecodes can manage the value they represent.

bytecode "ldc" pushes into the operand stack the content of an entry in the constant pool.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic