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され、メモリが再サークルされます。

于 2013-03-16T04:43:53.737 に答える
0

文字列リテラル(例"This is a new name")はインターンされているため、メソッドが終了した後もキャッシュされ、メモリに残ります。

ただし、通常、オブジェクトを参照している変数がスコープ外になると、オブジェクトはgcされます。

たとえばString newString = new String("This is a new name");、メソッドが戻るnewStringと、オブジェクトへの参照を保持する時間が長くなるため、オブジェクトはgcの対象になります。

注:これは、新しいString( "This is a new name")`new String("This is a new name")の代わりに1つの追加オブジェクトを明示的に作成する必要があるという意味ではありません。"This is a new name", because interning happens in both the cases. The difference is that with

于 2013-03-16T04:39:04.563 に答える
0

オブジェクトを宣言すると、その揮発性(したがってオブジェクトの内容)は、それを宣言したメソッド/オブジェクトの存続期間を持ちます。

于 2013-03-16T04:40:23.253 に答える
0

それへの参照を保持している限り、オブジェクトは引き続きメモリに残ります。文字列がどのオブジェクトからも参照されなくなると、ガベージコレクターになります。つまり、ある時点でメモリが回復されます。

于 2013-03-16T04:45:14.793 に答える
0

おかしなことに、あなたが尋ねているシナリオは、Javaメモリ管理の2つの側面と重複しています。つまり、あなたの答えは「はい」と「いいえ」の両方です。

String newString = "This is a new name";

この行は、静的な文字列リテラルを参照しているため、最初の割り当てからプログラムの最後までメモリに保持されます。コンパイラは、"This is a new name"変更されないことを保証できるため、これを実行します。したがって、メソッドが実行されるたびに、割り当て、再割り当て、および削除するのに無駄なCPUサイクルが発生します。

一方、ラインが例えばだった場合

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

これはリテラルではないためString、メソッドを新しく実行するたびに新しいオブジェクト()が作成されます。では、このオブジェクトはいつ割り当て解除されますか?によって参照されるため、メソッドの最後まで存続することを保証できますnewString。その後、次にガベージコレクタが実行されるまで存続します。ただし、これ以上参照するものはないため、とにかくアクセスすることはできません。

于 2013-03-16T04:47:16.163 に答える