1

I was playing with some examples of Collections from Oracle website

public class Timing {
 public static void method(){
 List numbers = new ArrayList();
 for (double i = 1; i <= Double.MAX_VALUE; i++)
 numbers.add(new Double(i));
 Collections.shuffle(numbers);
 List winningcombination = numbers.subList(0, 10);
 Collections.sort(winningcombination);
 }
 public static void main(String[] args)
 {
 long start = System.currentTimeMillis();
 method();
 long end = System.currentTimeMillis();
 System.out.println("time elapsed : " + (end-start));
 }
}

I tried to see how long it will take to do it for Double.MAX_VALUE. And I got this :

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at java.util.Arrays.copyOf(Unknown Source)
 at java.util.Arrays.copyOf(Unknown Source)
 at java.util.ArrayList.ensureCapacity(Unknown Source)
 at java.util.ArrayList.add(Unknown Source)

I there a way to fix this ?

trincot
356k37 gold badges280 silver badges338 bronze badges
asked Aug 10, 2011 at 15:24
1
  • 1
    The actual exception happens when the ArrayList chooses to grow (and copy its old contents to the new backing array) Commented Aug 10, 2011 at 16:07

8 Answers 8

17

Is there a way to allow you to create and store Double.MAX_VALUE objects in a Collection? No. There's not that much RAM on Earth. Double.MAX_VALUE is about 2 times ten to the 308th power: that's 2 followed by over 300 zeros. Give Best Buy a call, see how much they'd charge to put that in your computer.

answered Aug 10, 2011 at 15:27
Sign up to request clarification or add additional context in comments.

6 Comments

@OpenMind: The solution is not to attempt the impossible.
There is no solution. You cant store that much!
The solution is to use a much smaller upper limit for your loop -- no more than, say, a million or so.
@OpenMind, exactly what are you trying to do? Generate 10 random numbers that are guaranteed to not have duplicates? If so, look into pseudo-random number generators. Also, I don't understand why you are generating winning combinations of doubles rather than longs or alphanumerals etc.
Write a better algorithm, just store the already selected numbers and do a random again if you've got the same and you don't have enough.
|
5

Even if you had enough memory, ArrayList can have at most Integer.MAX_VALUE elements. Double.MAX_VALUE far exceeds said limit.

In this case, you ran out of memory during an add that caused the array list to grow.

answered Aug 10, 2011 at 15:27

1 Comment

Exceeds by "How much?" (I just want to see a big number ^^)
5

Yet another reason why your code cannot work: double can only represent integers exactly up to about 2^52 - after that, i++ will have no effect and the for loop will never terminate.

You should never use floating-point variables as loop counters. Use int or long instead.

answered Aug 10, 2011 at 15:33

5 Comments

Although I think there might already be problems if code tries to loop 2^52 times... ;-)
Well, it'll give him slightly unexpected results, at least. That, and because he actually tests i <= Double.MAX_VALUE, he's going to overflow i regardless...
#winces# I didn't realize the imprecision got that bad, even in the upper range... Oh, grr, it would have to increment in a (positive non-zero) power of ten after that, wouldn't it...
@X-Zero: power of two, actually. And it's not that the imprecision gets worse - it's always the same, relative to the magnitude of the number being represented. Once you're up to 2^52, an increase of 1 is (justly) assumed not to matter much. OTOH, the format can distinguish between 0.00000000000001 and 0.00000000000002 - Any attempt to represent an uncountably infinite set in will require some tradeoffs, and it's really quite marvelous how it can be done in only 64 bits and work quite well most of the time.
... I'm really showing my lack of a CS degree here, aren't I... That, and being too used to an AS/400 shop, where most stuff is being coded as BCDs
2

Instead of doing what you are currently doing, you should just obtain 10 random doubles, add them to an ArrayList and sort it. That is basically what your method is doing.

To obtain a random double, look at Random.nextDouble().

answered Aug 10, 2011 at 15:39

Comments

1

You are trying to allocate of the order of 10^308 values. That's a lot of values.

answered Aug 10, 2011 at 15:28

2 Comments

Put into a real perspective? 10^308 just looks small ;p
@pst 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000. Yup, still looks small...
0

Increasing the size of the heap will do. Just run the program with this argument:

-Xmx512m

It will increase your heap size to 512 MB. You can specify as much as you want: 1g, 2g and so on.

answered Aug 10, 2011 at 15:28

Comments

0
for (double i = 1; i <= Integer.MAX_VALUE; i++)
 numbers.add(new Double(i));
answered Aug 10, 2011 at 15:28

4 Comments

But how will this address the OutOfMemory exception? (A PC still won't come close.)
That's better, although you probably still don't have that much memory. That's about 2 billion objects, at least 12 bytes each, plus the array in the array list; so 24GB for the objects and another 8B for the array.
@Ernest: well, it's not completely impossible for a consumer-grade PC to have 24GB of RAM; in fact, in 5 years' time it will probably be normal.
Indeed, that's why I said "you probably still don't have that much". I have a server that does, but none of my desktops do!
0

In you loop:

for (double i = 1; i <= Double.MAX_VALUE; i++)
 numbers.add(new Double(i));

An ArrayList will just add the value to the ArrayList if there is room. If not it will increase the size of the ArrayList and then continue adding.

So what you are basically doing is using all the memory allocated in your heap when you are creating this ArrayList. If you make your ArrayList smaller you should be able to hold it in memory.

answered Aug 10, 2011 at 15:30

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.