0

我正在编写一个 java 应用程序并尝试对自己进行内存管理方面的教育。如果在一个已经创建的对象的方法中实例化一个String对象,这个String对象在方法执行后会存在内存中吗?举这个例子。执行 myObject.setNewName() 后内存中是否存在 newString?或者如果它们不是实例变量,java会销毁这些对象吗?

public class MyObject(){

    private String name;
    private Integer id;

    public myObject(Integer id, String name){
        this.id   = id;
        this.name = name;
    }

    public void setNewName(){

        String newString = "This is a new name";
        this.name = newString;
    }
}

另一个文件

MyObject myObject = new MyObject(4,"Bob");

myObject.setNewName();
4

6 回答 6

2

如果对对象的引用被保留在方法之外,例如分配给一个字段,那么当方法结束时,对象将不会被垃圾回收。

当方法结束时,仅分配给局部变量的对象将“不可访问”,因此将被标记为垃圾回收。

这一切都与范围有关。如果对对象的引用仍在范围内,它将保留在内存中。

于 2013-03-16T04:37:57.943 回答
1

字符串实际上是在一个常量池中创建的,并且会贯穿整个 JVM 生命周期。您可以通过以下方式对其进行检查:

    public static void main(String[] args) {
    aMethod();
    String str1 = "This is a string";
    System.out.println(System.identityHashCode(str1)); 
}

public static void aMethod(){
    String str0 = "This is a string";
    System.out.println(System.identityHashCode(str0));
}

str0 和 str1 实际上是相同的,因为它们的哈希码相等。

字符串是一种特定的对象,如果一个普通对象不再被任何人引用,它会在某个时候被 GC-ed 并且内存将被重新循环。

于 2013-03-16T04:43:53.737 回答
0

由于字符串字面量(例如"This is a new name")是实习的,因此即使在方法结束后,它们也会被缓存并保留在内存中。

但是,通常一旦引用对象的变量超出范围,对象就会被 gc'ed。

例如String newString = new String("This is a new name");,一旦方法返回,该对象将符合 gc 条件,因为newString持有该对象的引用的时间将更长。

注意:这并不意味着您应该使用new String("This is a new name")new "This is a new name", because interning happens in both the cases. The difference is that withString("This is a new name")` 而不是显式创建一个额外的对象。

于 2013-03-16T04:39:04.563 回答
0

当您声明一个对象时,它的易变性(以及对象内容)将具有声明它的方法/对象的生命周期。

于 2013-03-16T04:40:23.253 回答
0

只要您持有对它的引用,该对象仍将保留在内存中。一旦字符串没有被任何对象引用,它将成为可垃圾回收的,这意味着内存将在某个时候被回收。

于 2013-03-16T04:45:14.793 回答
0

有趣的是,您所询问的场景与 Java 内存管理的两个方面重叠,这意味着您的答案是肯定的和否定的。

String newString = "This is a new name";

从第一次分配到程序结束,这一行将保存在内存中,因为它引用了一个静态的字符串文字。编译器这样做是因为它可以保证"This is a new name"永远不会改变,因此每次运行该方法时分配、重新分配和删除它都是无用的 CPU 周期。

另一方面,如果这条线是,例如

String newString = new Object().toString();

这不是文字,因此String在方法的每次新运行期间都会创建一个新对象(即 a )。那么,这个对象什么时候被释放呢?您可以保证它将持续到方法结束,因为它被newString. 之后,它将一直存在到下次垃圾收集器运行时。但是,没有任何东西会再引用它,因此无论如何都无法访问。

于 2013-03-16T04:47:16.163 回答