开发者

Why am I getting an OutOfMemoryError in java?

I am working on a projecteuler problem, and I have run into an OutOfMemoryError.

And I don't understand why because my code was working beautifully (to my novice eyes at least :P).

Everything works just fine until the loop reaches 113383.

If someone could help me debug this it would be greatly appreciated because I don't understand at all why it i开发者_如何学Cs failing.

My Code

import java.util.Map;
import java.util.HashMap;
import java.util.Stack;

/*
* The following iterative sequence is defined for the set of positive integers:
n = n/2 (n is even)
n = 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13  40  20  10  5  16  8  4  2  1
It can be seen that this sequence (starting at 13 and finishing at 1) contains
10 terms. Although it has not been proved yet (Collatz Problem), it is thought 
that all starting numbers finish at 1. Which starting number, under one million,
produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
*/
public class Problem14 {

    static Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    final static int NUMBER = 1000000;

    public static void main(String[] args) {

        long start = System.currentTimeMillis();
        map.put(1, 1);      
        for (int loop = 2; loop < NUMBER; loop++) {
            compute(loop);
            //System.out.println(map);
            System.out.println(loop);
        }       
        long end = System.currentTimeMillis();
        System.out.println("Time: " + ((end - start) / 1000.) + " seconds" );
    }

    private static void compute(int currentNumber) {
        Stack<Integer> temp = new Stack<Integer>();
        /**
         * checks to see if current value is already 
         * part of the map. if it isn't, add to temporary
         * stack. also if current value exceeds 1 million,
         * don't check map or add to stack.
         */
        while (!map.containsKey(currentNumber)){
            temp.add(currentNumber);
            currentNumber = realCompute(currentNumber);
            while (currentNumber > NUMBER){
                currentNumber = realCompute(currentNumber);
            }
        }
        System.out.println(temp);
        /**
         * adds members of the temporary stack to the map
         * based on when they were placed in the stack
         */
        int initial = map.get(currentNumber) + 1;
        int size = temp.size();

        for (int loop = 1; loop <= size; loop++){
            map.put(temp.pop(), initial);
            initial++;
            //key is the top of stack
            //value is initially 1 greater than the current number that was
            //found at the map, then incremented by 1 afterwards;
        }
    }

    private static int realCompute(int currentNumber) {

        if (currentNumber % 2 == 0) {
            currentNumber /= 2;
        } else {
            currentNumber = (currentNumber * 3) + 1;
        }
        return currentNumber;
    }
}


Seems to me it's just what the error says: you're running out of memory. Increase the heap size with -Xmx (eg java -Xmx512m).

If you want to reduce the memory footprint, take a look at GNU Trove for a more compact (and faster) implementation of primitive maps (instead of using HashMap<Integer,Integer>).


I have the exactly same problem as you had... The problem actually lies with the "Stack temp", and change it to Long would be fine. It is a simple overflow.


Which OutOfMemory error is it? Heap, PermGen..? Probably need to increase heap size or permgen size.


you should define HashMap like: map = new HashMap(NUMBER).

you know, "Entry[] table" is the map data structure,auto capacity.

the reason for inital capacity:1,not array copy. 2,run faster.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜