字符串和内存管理

Xav*_*Gil 5 java string android memory-leaks memory-management

我正在努力了解Android(Java)中字符串和内存管理的情况.

为简化起见,请看一下这段简单的代码:

public void createArray(){
        String s = "";
        String foo = "foo";
        String lorem = "Lorem ipsum ad his scripta blandit partiendo, eum 
                 fastidii accumsan euripidis in, eum liber hendrerit an.";
        ArrayList<Item> array = new ArrayList<Item>();

        for( int i=0; i<20000; i++ ){
            s = foo.replace("foo", lorem);
            array.add( new Item(s) );
        }
        System.gc();
    }

private class Item{
    String name;

    public Item(String name){
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果执行,createArray将在内存中分配超过5Mb.即使使用该System.gc()指令,循环后也不会释放内存.

现在,如果我们更换s = foo.replace("foo", lorem);s = lorem;,分配的内存只能由0.5MB增加.

我需要了解提高应用程序性能的方法.

任何人都可以解释在这样的情况下我应该如何替换字符串?为什么System.gc()不解除内存?

谢谢.

更新:

感谢您的回答,现在我明白这System.gc()只是一个提示.

澄清另一个问题(重要的问题):

如何动态生成20000个字符串("foo1","foo2"..."foo20000")将它们添加到ArrayList并且不会耗尽内存?如果这20000个字符串是静态的,则它们在内存中的分配不会超过0.5Mb.此外,如果s = foo.replace("foo", lorem)创建一个全新的String,为什么我的函数分配5Mb,这是内存的10倍?不应该在1Mb左右?

(我已经考虑过一种解决方法,但我想确保没有使用这么大的内存就无法动态生成字符串)

dle*_*lev 5

replaceString每次调用时都会生成一个全新的对象,因为Java中的字符串是不可变的,因此不能将修改设置为"静止".此外,您将其添加StringArrayList将保留对新对象的引用,以防止收集它.