回答編集履歴
3
Timer が発動する前に GC が走ると を追加
test
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
メソッド実行中は、解放対象にはなりません。
|
10
10
|
|
11
11
|
ただし、SubClass が Timer のインスタンスを保持していないので、危ういコードになっています。
|
12
|
-
次のように SubClass のインスタンスを参照していても、Timer のインスタンスが解放され、TimerCallback が呼ばれません。
|
12
|
+
次のように SubClass のインスタンスを参照していても、Timer が発動する前に GC が走ると Timer のインスタンスが解放され、TimerCallback が呼ばれません。
|
13
13
|
|
14
14
|
```C#
|
15
15
|
using System;
|
2
大幅に書き換え
test
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
「サブクラスで処理している途中に」というのが「TimerCallback を実行中」というのであれば、1,2,3 の回答は「解放されない」ということになります。
|
2
|
+
|
3
|
+
「ガベージ コレクションの基礎」
|
4
|
+
[https://docs.microsoft.com/ja-jp/dotnet/standard/garbage-collection/fundamentals](https://docs.microsoft.com/ja-jp/dotnet/standard/garbage-collection/fundamentals)
|
5
|
+
の「メモリの解放」のところに
|
6
|
+
「アプリケーションのルートには、静的フィールド、スレッドのスタック上のローカル変数、CPU レジスタ、GC ハンドル、ファイナライズ キューが含まれています。」
|
1
|
-
|
7
|
+
という記述があります。
|
8
|
+
|
9
|
+
メソッド実行中は、解放対象にはなりません。
|
10
|
+
|
2
|
-
SubClass が Timer のインスタンスを保持していないので、危ういコードになっています。
|
11
|
+
ただし、SubClass が Timer のインスタンスを保持していないので、危ういコードになっています。
|
3
|
-
次のコードを実行してみてください。
|
4
|
-
TimerCallback が呼ばれることなくデストラクタが実行されるのが確認できます。
|
5
|
-
|
12
|
+
次のように SubClass のインスタンスを参照していても、Timer のインスタンスが解放され、TimerCallback が呼ばれません。
|
6
13
|
|
7
14
|
```C#
|
8
15
|
using System;
|
@@ -11,9 +18,7 @@
|
|
11
18
|
class Program
|
12
19
|
{
|
13
20
|
static void Main(string[] args) {
|
14
|
-
new SubClass();
|
21
|
+
var s = new SubClass();
|
15
|
-
GC.Collect();
|
16
|
-
GC.WaitForPendingFinalizers();
|
17
22
|
GC.Collect();
|
18
23
|
GC.WaitForPendingFinalizers();
|
19
24
|
Console.WriteLine("何かキーを押してください。");
|
@@ -30,17 +35,13 @@
|
|
30
35
|
private void TimerCallback(object obj) {
|
31
36
|
Console.WriteLine("TimerCallback");
|
32
37
|
}
|
33
|
-
|
34
|
-
~SubClass() {
|
35
|
-
Console.WriteLine("Finalize");
|
36
|
-
}
|
37
38
|
}
|
38
39
|
```
|
39
40
|
|
40
41
|
下のように Timer のインスタンスを保持すれば TimerCallback は実行されます。
|
41
42
|
IDE0052 の警告が出るので抑止してください。
|
42
43
|
|
43
|
-
```
|
44
|
+
```C#
|
44
45
|
class SubClass
|
45
46
|
{
|
46
47
|
#pragma warning disable IDE0052
|
@@ -52,12 +53,3 @@
|
|
52
53
|
}
|
53
54
|
```
|
54
55
|
|
55
|
-
■質問2,3について
|
56
|
-
両方とも、TimerCallback を実行中にGCが起きると、外部から参照されなくなった SubClass はどうなるか?という質問かと思います。
|
57
|
-
「ガベージ コレクションの基礎」
|
58
|
-
[https://docs.microsoft.com/ja-jp/dotnet/standard/garbage-collection/fundamentals](https://docs.microsoft.com/ja-jp/dotnet/standard/garbage-collection/fundamentals)
|
59
|
-
の「メモリの解放」のところに
|
60
|
-
「アプリケーションのルートには、静的フィールド、スレッドのスタック上のローカル変数、CPU レジスタ、GC ハンドル、ファイナライズ キューが含まれています。」
|
61
|
-
という記述があります。
|
62
|
-
つまり、メソッドが実行されている場合、そのインスタンスは回収対象外ということになろうかと思います。
|
63
|
-
|
1
質問2、3について回答
test
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
■ 質問1について
|
1
2
|
SubClass が Timer のインスタンスを保持していないので、危ういコードになっています。
|
2
3
|
次のコードを実行してみてください。
|
3
4
|
TimerCallback が呼ばれることなくデストラクタが実行されるのが確認できます。
|
5
|
+
GC を2回実行していますが、1回目で Timer のインスタンスが回収され、2回目で SubClass の回収が行われます。
|
4
6
|
|
5
7
|
```C#
|
6
8
|
using System;
|
@@ -49,3 +51,13 @@
|
|
49
51
|
timer = new Timer(TimerCallback, null, 5 * 1000, Timeout.Infinite);
|
50
52
|
}
|
51
53
|
```
|
54
|
+
|
55
|
+
■質問2,3について
|
56
|
+
両方とも、TimerCallback を実行中にGCが起きると、外部から参照されなくなった SubClass はどうなるか?という質問かと思います。
|
57
|
+
「ガベージ コレクションの基礎」
|
58
|
+
[https://docs.microsoft.com/ja-jp/dotnet/standard/garbage-collection/fundamentals](https://docs.microsoft.com/ja-jp/dotnet/standard/garbage-collection/fundamentals)
|
59
|
+
の「メモリの解放」のところに
|
60
|
+
「アプリケーションのルートには、静的フィールド、スレッドのスタック上のローカル変数、CPU レジスタ、GC ハンドル、ファイナライズ キューが含まれています。」
|
61
|
+
という記述があります。
|
62
|
+
つまり、メソッドが実行されている場合、そのインスタンスは回収対象外ということになろうかと思います。
|
63
|
+
|