方法调用的java内存使用情况

use*_*956 5 java memory-management

我正在尝试解决codeeval上的问题,但遇到了使用太多内存的问题.在我的代码中,由于大量输入是不可避免的,因此有一个循环运行很多次(~10,000 ^ 2).我注意到如果我运行循环并且在每次迭代时什么也不做,我总共使用大约6MB的内存和其他代码.但是,如果我在循环中添加一个简单的方法调用,它只调用一个返回false的函数,那么我的内存使用量会跳到20MB.

为什么是这样?在函数调用完成后,是否应该为每个函数调用分配的内存被释放?

编辑:完整的代码非常大,与post无关,但这个代码片段就是我所描述的.如果我不包括该foo()调用,我的代码作为一个整体运行使用6MB的内存.如果我包含该foo()调用,则我的代码作为一个整体使用20MB内存运行.foo()我实际代码中的方法确实是一样的(返回false)因为我想测试内存使用情况.

这是针对codeeval的编码挑战,所以问题应该可以用他们允许的任何语言解决,所以java应该没问题.

编辑:我已经重构了我的一些代码,以便我可以提取整个函数来向你们展示.这仍然产生前面描述的相同结果.产生奇怪行为的函数调用是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;
}
Run Code Online (Sandbox Code Playgroud)

ski*_*iwi 0

您遇到的问题是,现在它将首先调用一个方法,即foo()循环运行多少次。
方法最终会出现在调用堆栈上,需要额外的时间来处理,要获得更深入的解释,恐怕您需要谷歌。

关键是,当您放入return falseinside时bar(),它​​不管理调用堆栈,因此使用更少的内存并且可能更快。

我相信,在某些时候,如果在 Hotspot JVM(默认的)上运行,JVM 将内联您的foo()方法调用,从而导致行为就像您return false直接在bar(). 它何时优化,以及是否优化,取决于 JVM 参数和您的特定版本/系统。

然而,即使它已经优化,内存也已经被 JVM 占用了。即使 JVM 不再使用该内存,它也会拒绝将其返还给您的操作系统,因此您仍然会观察到较高的内存使用率。