• Post Reply Bookmark Topic Watch Topic
  • New Topic

Integer vs int  RSS feed

 
Sandeep Jindal
Ranch Hand
Posts: 180
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I am using a recursive function where-in I am using creating a temporary int variable. e.g the code below


e.g.


In the above code, for optimization if I do this:



That makes x and y eligible for garbage collection.

So for the above case I would say use Integer instead of int. I that correct to say? Is that correct to say in general?



 
Em Aiy
Ranch Hand
Posts: 226
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
it does make those objects referred by x and y available for "garbage collector". but you can never be sure about java garbage collection, will it remove those objects or not.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That makes x and y eligible for garbage collection.

So for the above case I would say use Integer instead of int. I that correct to say? Is that correct to say in general?


How is that an optimization? Isn't creating *no* objects, and hence, no need to GC at all, better than creating an object, going through unboxing and boxing, and then having to GC?

Henry
 
fred rosenberger
lowercase baba
Bartender
Posts: 12564
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
in the first case, when you create primitives, they are stored on the stack. So, once you start 'unwinding' your recursive calls, when that method ends, those values are automatically popped off and memory is instantly recovered.

in the second case, you create an object on each successive call. when you unwind, the reference is popped off, but the object still exists on the heap until the GC is run - which may NEVER happen.

Note - in the second case, you create both a reference AND an object. in the first case, you are just creating a primitive. I'm not sure what the size is of a reference, but i would guess that the memory usage of a reference + an object is at least the same size if not greater than an int primitive.

And Henry also raises a good point... I'm just talking about MEMORY optimization. When you look at speed issues, you have 'creating a primitive and assigning a value to it' vs. 'creating a reference, creating an object, assigning the object to the reference, a bunch of auto-boxing and un-boxing...'

I would think this would take LONGER. The only way to know for sure is to use some kind of profiler to watch both memory and speed.

But all that should wait. The best way to do things is to write the clearest, simplest code you can that works. Only after you've done that, see if it's too slow. THEN find where the real bottlenecks are - it is almost ALWAYS the case the code slows down somewhere else than where you think.
 
Himanshu Kansal
Ranch Hand
Posts: 257
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A reference would take 1 byte. What the object takes is dependent on what it holds. So it obviously is bulkier than the primitive.

Moreover, by creating a reference and objects additional overhead is put on the compiler to maintain the reference in the heap. Primitives go to the stack and a single compiler call.

It is simple, if you need to do some operations on your values, that need them to be an object, take the second approach. Else the first one is better.

Regards
 
Campbell Ritchie
Marshal
Posts: 56562
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Surely a reference on a 32-bit computer is 4 bytes?
 
Sandeep Jindal
Ranch Hand
Posts: 180
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Totally agree with Fred and Henry.
Performance would definitely slower (may not be too much though).

Also agreed about the stack thing. GC may never run to clean the Integer objects but primitives would anyways we removed while 'unwinding' the stack.

So conclusion - Use primitive whenever you can.

But I had a different requirement. My recursive stack is huge. It is traversing tree, and also using too much of memory.
Thus, since too many recursive calls... say is at 1000th recursive method.. if JVM needs some memory it would call GC to free memory. If my x and y are Objects it would help GC. But if they are primitives it would not help GC. So think in that case using Integer instead of int would be right choice. Correct?
 
Campbell Ritchie
Marshal
Posts: 56562
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sandeep Jindal wrote:But I had a different requirement. My recursive stack is huge. It is traversing tree, and also using too much of memory.
Thus, since too many recursive calls... say is at 1000th recursive method.. if JVM needs some memory it would call GC to free memory. If my x and y are Objects it would help GC. But if they are primitives it would not help GC. So think in that case using Integer instead of int would be right choice. Correct?
No
 
Sandeep Jindal
Ranch Hand
Posts: 180
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:No

Thanks for your answer, but can please elaborate on it please?
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sandeep Jindal wrote:
Campbell Ritchie wrote:No

Thanks for your answer, but can please elaborate on it please?


If x and y were objects, then yes, there is a component on the heap that can be GC'ed. But references take up space too, and it (local variables) lives on the stack. In terms of size, on a 32 bit JVM, a references is 4 bytes, and on a 64 bit JVM, a reference is 8 bytes. In comparison, an int takes up 4 bytes.

So... what you are proposing doesn't shift the memory from the stack to the heap. It just add memory demand on the heap. And at best, doesn't change the memory demand on the stack.

Henry
 
Steve Fahlbusch
Bartender
Posts: 612
7
Mac OS X Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Additionally,

If the references are still referencing the objects in the heap, then those objects can not be GC'ed. Only when those references are cleared can the objects in the heap be candidates for GCing.
 
Sandeep Jindal
Ranch Hand
Posts: 180
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Steve, in the snippet mentioned, I am making the reference to null this it is eligible for GC.

To put what Henry has said in my words:
Agreed that the Objects are eligible for GC, but the stack still has the references and the references itself take huge memory(4 bytes on 32 bit JVM, 4 bytes on 64 bit JVM) and int always takes 4 bytes only. Thus if not greater using Integer even in my example would take atlteast the same memory as for int.

Thus int is always recommended over Integer. Correct?
 
Steve Fahlbusch
Bartender
Posts: 612
7
Mac OS X Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would have to say that if you have a recursive algorithm that is setting references to null and keeps them in memory, then your algorithm really needs to be re-evaluated, as this makes no sense.

 
Campbell Ritchie
Marshal
Posts: 56562
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sandeep Jindal wrote:Thus int is always recommended over Integer. Correct?
No. There are instances, eg in the Collections Framework, where Integers are required.
 
fred rosenberger
lowercase baba
Bartender
Posts: 12564
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would like to re-emphasize my earlier point that got lost...

WRITE THE CODE THAT MAKES THE MOST SENSE, AND IS EASIEST TO READ AND UNDERSTAND.

at some point, maybe a week, maybe a month, maybe 5 years from now, you or someone else will be re-visiting your code. Don't make it so complicated they want to hunt you down and do nasty things to you.

once you have that code working, see if you have problems. If you have memory issues, then consider re-factoring it... but FIND OUT WHERE THE MEMORY PROBLEM IS. Use a profiler to determine EXACTLY what is sucking up all the memory. If you just guess, you're probably gonna guess wrong. You'll spend days or weeks tweaking something, and only get a modest gain. Eventually you find out something stupid that only takes 5 minutes to fix would have solved the original problem.

Same goes for speed issues.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!