2

I'm tinkering a bit with Java but have a lot of experience in some other languages. I have a test problem that I know solution to (and can easily produce in Python and C++). But running the following Java code gives an

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

I'm wondering if I'm making a simple mistake, I would not expect the memory footprint of this program to be very large at all:

public static void main(String[] args) { ArrayList<Integer> longest_sequence = new ArrayList<>(); ArrayList<Integer> this_sequence; int n = 0; for (int i = 1; i < 1000000; i++) { this_sequence = new ArrayList<Integer>(); n = i; this_sequence.add(n); while (n != 1) { if (n % 2 == 0) { n = n / 2; } else { n = 3*n + 1; } this_sequence.add(n); } if (this_sequence.size() > longest_sequence.size()) { longest_sequence = this_sequence; } } System.out.println(longest_sequence.get(0)); System.out.println(longest_sequence.size()); } 

To clarify a bit more:

A new list is created in each iteration of the program. It is either kept by assigning the longest_sequence to it, or it is discarded and overwritten by a new list instance.

I'm guessing my assumptions about that are incorrect, and instances are being preserved? The size of the lists should not be a problem (about 500 elements for the largest one).

7
  • You could try increasing the heap space for the running program. It probably defaults to less than 1G Commented Apr 29, 2017 at 17:07
  • Try using this_sequence.clear(), though, and use only one reference to the list rather than recreate in the loop Commented Apr 29, 2017 at 17:08
  • probably, the memory footprint will be very big due to your while loop, how can you know how big the largest one is ? Commented Apr 29, 2017 at 17:09
  • What is your estimate of heap memory your code requires? Commented Apr 29, 2017 at 17:13
  • 4
    The problem here is that the integer is overflowing and your Collatz conjecture code is not terminating at 1 as you expect. Replace int with long and everything is fine. This is, of course, still a wildly inefficient way to measure the length of a sequence which doesn't require keeping anything in memory at all. Commented Apr 29, 2017 at 17:17

3 Answers 3

2

It will fail even if you increase your heap space.

For n = 113383, an operation make you go through Integer limit and n becomes negative and this is ending in a infite loop.

It works if you change Integer by Long.

Sign up to request clarification or add additional context in comments.

1 Comment

Yep, and a few minutes after I posted this question I looked at my old c++ code and immediately realized that I was hitting an integer overflow. I've been spending too much time in dynamically typed languages I think! Thank you.
0

I think the easiest to avoid this is to add memory using -Xmx flag

https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html here's official docs to read more about it

Comments

0

to change the VM for Eclipse you can change the amount of the MV from Windows> Preferences> Java> Installed JREs from there select the JRE and click edit, then write in the Default VM Arguments: to -Xmx1024M or any other amount of memory ...

Well, it's fairly self-explanatory: you've run out of memory.

You may want to try starting it with more memory, using the -Xmx flag, e.g.

java -Xmx2048m [whatever you'd have written before] This will use up to 2 gigs of memory.

See the non-standard options list for more details.

2 Comments

Thank you, the process of assigning more memory to the VM makes sense, but is sort of orthogonal to my question: Why is this program running out of memory?
The answer to the question 'why is this running out of memory' can't really be 'just add more memory'.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.