Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java memory usage from method call

I'm trying to solve a problem on codeeval but am running into a problem with using too much memory. In my code there is a loop that runs many many times (~10,000^2) due to a large input that is unavoidable. I noticed that if I run the loop and do nothing on each iteration I use about 6MB of memory in total with my other code. However, if I add a simple method call in the loop that just calls a function that returns false, my memory usage jumps to 20MB.

Why is this? Shouldn't the memory allocated for each function call get deallocated after the function call is finished?

EDIT: The full code is quite large and irrelevant to post but this snippet is what I described. If I do not include the foo() call, my code as a whole runs using 6MB of memory. If I include the foo() call, my code as a whole runs using 20MB of memory. The foo() method in my actual code does literally the same thing (return false) because I wanted to test out the memory usage.

This is for a coding challenge on codeeval so the problem should be solvable in any language they allow so java should be fine.

EDIT: I've refactored some of my code so that I could pull out an entire function to show you guys. This still produces the same result described before. The function call that produces the weird behavior is are_friends().

ArrayList<ArrayList<Integer>> graph(String[] word_list) {

    ArrayList<ArrayList<Integer>> adj_list = new ArrayList<ArrayList<Integer>>();

    for (int i = 0; i < word_list.length; i++) {
        adj_list.add(new ArrayList<Integer>());
    }

    for (int i = 0; i < word_list.length; i++) {
        for (int j = i + 1; j < word_list.length; j++) {
            if (are_friends(word_list[i], word_list[j])) {
                adj_list.get(i).add(j);
                adj_list.get(j).add(i);
            }
        }
    }

    return adj_list;
}

boolean are_friends(String a, String b) {
    return false;
}
like image 539
user1529956 Avatar asked Nov 10 '22 12:11

user1529956


1 Answers

If I include the foo() call, my code as a whole runs using 20MB of memory.

You should be careful about definitive claims on the memory usage of a Java program.

  • do you mean retained memory?
  • do you mean "I saw it in Task Manager/top/other process-monitoring tool"?
  • do you mean "I profiled it with VisualVM or similar, and that was the peak heap usage"?

With each of these approaches you'll probably be getting wildly different measurements.

One relevant indicator of memory usage would be setting the maximum heap size with -Xmx to, say, 16 MB, and seeing whether your program is able to complete error-free in one or the other of its forms. Note that this will limit only the heap and not the stack or any other support memory areas used by the JVM.

Without limiting the heap as above the JVM is free to use as much of it as it sees fit, keeping a lot of garbage around to avoid GC stalls.

like image 179
Marko Topolnik Avatar answered Nov 14 '22 23:11

Marko Topolnik