1

From this discussion i need to write a program to know the answer to question:"if there are more objects than maxvalue of int, then what does jvm assign as an address to an object?",

With the below setting in eclipse.ini

-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.200.v20131025-1931
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
--launcher.appendVmargs
-vmargs
-Dosgi.requiredJavaVersion=1.6
-Xms6144m
-Xmx6144m

and below program,

class SubClass {
    int x = 4;
    int getX(){
        return x;
    }
}

    public class Dummy2 {

        public static void main(String[] args){

            SubClass obj[] = null;
            obj = new SubClass[Integer.MAX_VALUE];
            for(int i = 0; i < Integer.MAX_VALUE; i++){
                obj[i] = new SubClass();
            }

            SubClass objRef1 = new SubClass();
            System.out.println(objRef1);
            System.out.println(objRef1.hashCode());

            SubClass objRef2 = new SubClass();
            System.out.println(objRef2);
            System.out.println(objRef2.hashCode());




        }

    }

am getting error:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

My goal is to see the value of object's address and the hashcode generated for last two objects.

Am using 64 bit jvm running on 64 bit Windows 7 OS which provides virtual space of 8TB for each native user level process. Hardware has 8GB RAM chip.

Please help me!!

trincot
  • 317,000
  • 35
  • 244
  • 286
overexchange
  • 15,768
  • 30
  • 152
  • 347

2 Answers2

4

There is a number of misconceptions here.

  • The Object.hashCode() is a randomly generated number which is storing in the object's header and it doesn't change when the object moves.
  • Windows doesn't allow the JVM to use virtual memory, you can't create a JVM heap which is larger than main memory.
  • you need at least 20 GB of JVM memory for 2 billion elements.
  • An array can't have more than Integer.MAX_VALUE elements, but you can have an array of arrays (or arrays, of arrays)

My goal is to see the value of object's internal address and the hashcode generated for last two objects.

They are random so there is not difference between them and the first elements.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • `Windows doesn't allow the JVM to use virtual memory, you can't create a JVM heap which is larger than main memory.` are your sure? http://msdn.microsoft.com/en-us/library/windows/desktop/aa384271(v=vs.85).aspx – overexchange Dec 26 '14 at 17:13
  • @overexchange you can try it if you like and see what happens ;) – Peter Lawrey Dec 26 '14 at 17:21
  • try what? are you suggesting some eclipse settings? – overexchange Dec 26 '14 at 17:24
  • @overexchange I am not saying that over committing managed memory works well on linux either. The difference is that on linux it might lock up and you can kill the process. On windows you are more likely to need a power cycle. Either way you don't want a heap of more than about 80% of main memory. – Peter Lawrey Dec 26 '14 at 17:30
  • i dont care if RAM chip is 4GB chip, this is what am trying to say – overexchange Dec 26 '14 at 17:32
  • @overexchange I agree the size of main memory doesn't matter you just can't use that size or larger as a JVM. – Peter Lawrey Dec 26 '14 at 17:34
3

I'm assuming you're asking in regards to this.

You don't necessarily need to create more than Integer.MAX_VALUE objects. You just need to create some until there is a collision. You can do that relatively easily.

public static void main(String[] args) throws Exception {
    final int LENGTH = Integer.MAX_VALUE / 256;
    Object[] values = new Object[LENGTH];
    int count = 0;
    for (int i = 0; i < Integer.MAX_VALUE; i++) {
        Object o = new Object();
        int hashCode = o.hashCode();
        if (hashCode > LENGTH)
            continue;
        if (values[hashCode] != null) {
            System.out.println("found after " + count + ": " + values[hashCode] + " same hashcode as " + o);
            System.out.println(values[hashCode] == o);
            System.exit(0);
        } else {
            System.out.println(hashCode);
            values[hashCode] = o;
            count++;
        }
    }
}

For example, on my machine, this stops after 4712 new instances with a hashCode smaller than Integer.MAX_VALUE / 256. This means that two Object instances, which weren't eligible for GC, had the same hashCode.

The above prints

...
5522036
4166797
5613746
found after 4712: java.lang.Object@6aca04 same hashcode as java.lang.Object@6aca04
false
Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • in my machine this above program always says `:java.lang.ArrayIndexOutOfBoundsException: 8388607` which is intmax/256, am trying with intmax/8 now. r u running with 64 bit jvm? – overexchange Dec 26 '14 at 17:49
  • @overexchange With the exact code above? You should be protected with the `if (hashCode > LENGTH)`. – Sotirios Delimanolis Dec 26 '14 at 17:51
  • @overexchange Yes, 64 bit JVM. Tune the `LENGTH` to fit the amount of memory available to you. – Sotirios Delimanolis Dec 26 '14 at 17:55
  • `Object[] values = new Object[LENGTH];` hashcodes given to these objects can be greater than value of LENGTH, right? so am still not clear with condition (hashCode > LENGTH) – overexchange Dec 26 '14 at 18:01
  • @overexchange So that you don't run out of memory, we set a smaller `LENGTH`. However, `hashCode` can return something bigger than `LENGTH`. If we see such a `hashCode`, we just skip it. That's why I put a `continue`. – Sotirios Delimanolis Dec 26 '14 at 18:03
  • But if i set LENGTH to intmax/256 and remove the `if(hashcode>LENGTH){}` condition, i see outofmemory exception without program getting started, i did not get this point. – overexchange Dec 26 '14 at 18:15
  • @overexchange Set `LENGTH` to something smaller than `Integer.MAX_VALUE / 256`. – Sotirios Delimanolis Dec 26 '14 at 18:17
  • Another point, as `hashCode()` is actually converting the address to an integer value in `class Object`, How `hashCode()` is generating same integer `6aca04` for objects that has different addresses? because `values[hashCode] == o` is false. – overexchange Dec 26 '14 at 18:38
  • @overexchange This goes back to [this](http://stackoverflow.com/a/27658753/438154) answer. Maybe the JVM is using 64bit address (a `long`). An object at `0L` would have the same `hashCode` as an object at `4294967297L`. – Sotirios Delimanolis Dec 26 '14 at 18:40
  • can we display object's address as well? – overexchange Dec 26 '14 at 18:41
  • @overexchange No, that is an implementation detail. The Java Language doesn't care about it. (You may be able to do it with the `Unsafe` class.) – Sotirios Delimanolis Dec 26 '14 at 18:43