6

So I just learned when you declare a variable of type Object ( i.e. Object a; ), a 32-bit space is allocated for that variable. Inside this variable/reference, there is a memory address to an actual Object.

Now let's pretend I have a large enough amount of memory to do this.

What would happen if I created more than 4,294,967,296 (232) variables of type Object and tried assigning them to a distinct Object? Would some variables/references get the same memory addresses due to integer overflow? Meaning it's impossible to have references to more than 4,294,967,296 Objects in memory?

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
Kacy Raye
  • 1,312
  • 1
  • 11
  • 14
  • 1
    You would get `OutOfMemoryError`. – Luiggi Mendoza Jul 15 '13 at 02:38
  • @LuiggiMendoza Even if I had enough memory to contain all the Objects and references ? – Kacy Raye Jul 15 '13 at 02:39
  • Actually, the space allocated to a a variable of type Object is dependent on the JVM you are running. If you had a machine with the capability to allocate 2^^32 variables, perhaps it would represent an object some other way. It wouldn't make any difference to the java code in your program. The question doesn't really make any sense; you're either forgetting that the 32-bit variable is a specific implementation, or that that specific implementation cannot support that many object references. – arcy Jul 15 '13 at 02:49
  • 1
    References will be on "Stack" (not on Heap), so I guess it will be StackOverflowError, if you don't have enough slots to create references variables for the Object. – kosa Jul 15 '13 at 02:53
  • @Nambari yes you're right. – Luiggi Mendoza Jul 15 '13 at 03:12
  • (2 years later...) lol why would I ask this... – Kacy Feb 09 '15 at 13:05

2 Answers2

3

So I just learned when you declare a variable of type Object ( i.e. Object a; ), a 32-bit space is allocated for that variable. Inside this variable/reference, there is a memory address to an actual Object.

(When you talk about "a 32-bit space", IT folks will immediately think you are referring to an address space ... and a 32-bit address space gives you 2^32 bytes of storage!!)

So assuming that you actually mean "32 bits of space" what you are saying might be right, or it might be wrong. For a 32-bit JVM, references are indeed 32 bits long, and that means that your program can (in theory) refer to at most 2^32 distinct objects, of any kind. Even representing 2^32 distinct (32-bit) references will take 2^34 bytes.

On the other hand, if you are running your program on a 64-bit JVM, the size of a reference is 64-bits, and that means your program can (in theory) refer up to 2^64 distinct objects.

But this is all theoretical. The problem is that on a 32-bit machine, your program won't have enough memory to represent that many distinct objects. A minimal Java object on a 32-bit machine occupies (at least) 8 bytes. So even if you have the entire address space available you'd only be able to represent 2^29 objects. And in practice the OS doesn't provide the JVM that much memory. Indeed, depending on the OS, it may get at most 2 to 3Gb of the possible 4Gb of address space.


Of course, if you run a 64-bit JVM (on a 64-bit OS / and 64-bit capable hardware), you have a larger space for your object references AND you can have more memory to represent them. But you are still going to "hit the wall" eventually ... due to hardware limitations.

It is worth noting that Java has a variety of other inherent limits too. For instance, arrays can have at most 2^31 elements, Strings can have at most 2^31 characters, String literals are limited to 2^16 characters, and so on. These limits more fundamental than the 32 vs 64 bit reference limit.


FOLLOWUP

So to make long stories short, there will always be a pre-determined wall no matter how much memory I force my operating system to dedicate to my program at compile time ?

That is correct. (Sort of. You can't force the OS to dedicate memory to your program at compile time. The memory size is determined when you launch the program, not when you compile it.) Basically, you have the following "knobs" to twiddle ... at program launch time:

  • The JVM (32 vs 64 bit) places a bound on the amount of memory that is addressable, and determines whether references are 32 or 64 bits. (Note that this is a runtime choice. Compiled bytecode files are identical for 32 and 64 bit.)

  • The -Xms and -Xmx say how big the heap should be ... subject to the constraints of addressability and the amount of memory that the OS is prepared to give the JVM process.

  • There is also a Compressed OOPS feature that is relevant for a 64-bit JVM, but it is typically on by default.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • So to make long stories short, there will always be a pre-determined wall no matter how much memory I force my operating system to dedicate to my program at compile time ? If you can answer that question, I will gladly accept this answer :) – Kacy Raye Jul 15 '13 at 05:36
  • It is true that there will always be a pre-determined wall at a point depending on whether your JVM is 32-bit or 64-bit. (Though you can't force the OS to dedicate any amount of memory to your program at compile time; as Stephen stated, you can only do that at runtime.) – Louis Wasserman Jul 15 '13 at 17:34
  • "It is absolutely idiotic to have 64-bit pointers when I compile a program that uses less than 4 gigabytes of RAM. When such pointer values appear inside a struct, they not only waste half the memory, they effectively throw away half of the cache."---[Donald Knuth](http://www-cs-faculty.stanford.edu/~uno/news08.html) – jason Aug 04 '13 at 13:26
  • @Jason - Interesting quote, but it relates to a different problem in a different programming language. – Stephen C Aug 04 '13 at 16:37
0

While @rcook's comment is correct with regards to your specific example, @Nambari has touched on the fundamentals of how memory is managed. If you don't have enough slots in memory to allocate the references then the stack will overflow. Much like how you cannot add an N+1th element to an array of size N, the same fundamental principle applies.

travega
  • 8,284
  • 16
  • 63
  • 91
  • Well what if I was running on a JVM that allocated 32 bits per variable, but I dedicate a ton of memory to the program when compiling ( let's pretend the amount of memory I allow my program to use is more than enough ) ? Then the amount of room on the stack and heap wouldn't be a problem. What then? – Kacy Raye Jul 15 '13 at 03:06
  • @KacyRaye you need at least 16GB ram on each stack and heap, so when you find this dedicated server with at least 32GB ram, do your tests and answer yourself :). – Luiggi Mendoza Jul 15 '13 at 03:09
  • @LuiggiMendoza hahaha that comment made me laugh. Lol I guess we'll just never know. – Kacy Raye Jul 15 '13 at 03:12
  • @KacyRaye: I don't have much experience with implementation internals, but my theory is, there are always limitations, if you break it, it fails, no other work around. Breaking it is not that hard. Simple recursion with no condition met is enough. – kosa Jul 15 '13 at 03:13