Mut*_*pan 5 c# garbage-collection dispose reference object
我尝试使用下面的代码,得到的输出为 1000。我听说分配对象必须共享引用,而不是复制整个对象内存。这里的结果是不同的。任何人都可以帮忙吗?
public aaaaa ad = new aaaaa();
static void Main(string[] args)
{
Program p = new Program();
p.fun1();
p.fun2();
}
public void fun1()
{
using(smallclass s = new smallclass())
{
s.j = 1000;
ad.fun1(s);
}
}
public void fun2()
{
ad.fun2();
}
Run Code Online (Sandbox Code Playgroud)
public class aaaaa
{
public smallclass h = new smallclass();
public void fun1(smallclass d)
{
h = d;
}
public void fun2()
{
Console.WriteLine(h.j);
}
}
public class smallclass:IDisposable
{
public int j = 9;
public void Dispose()
{
GC.SuppressFinalize(this);
}
}
Run Code Online (Sandbox Code Playgroud)
更新:我预计会出现对象引用异常,因为引用的内存已在 p.fun1(); 中处置;
这是一个简单的例子,分配是如何工作的
using System;
namespace ConsoleApplication1
{
internal class Program
{
private static smallclass objA = new smallclass();
private static smallclass objB = new smallclass();
private static void Main(string[] args)
{
showValues();
objA.value = 1000;
showValues();
objB = objA;
showValues();
objA.value = 1055;
showValues();
}
private static void showValues()
{
Console.WriteLine("objA.value: " + objA.value);
Console.WriteLine("objB.value: " + objB.value);
Console.ReadLine();
}
}
internal class smallclass : IDisposable
{
public int value = 0;
public void Dispose()
{
//Here you can remove eventHandlers
//or do some other stuff before the GC will play with it
}
}
}
Run Code Online (Sandbox Code Playgroud)
就像你可以看到的
首先我们创建 2 个对象objA
,objB
然后我们显示预期的值,它们都是 0
之后我们将 的值增加到objA
1000,a 的值为objA
1000,并且 的值objB
保持为 0
现在我们进行分配objA
,objB
因此值objB
也为 1000
如果我们现在将 的值更改objA
为 1055,则objB
get 的值也会更改,因为objB
它不再是一个单独的对象,它现在像以前一样拥有相同的objA
引用
现在我将向您展示如何根据您的示例获得错误
将你的更改aaaaa class
为:
public class aaaaa
{
public WeakReference<smallclass> h;
public void fun1(smallclass d)
{
h = new WeakReference<smallclass>(d);
}
public void fun2()
{
smallclass k;
if(h.TryGetTarget(out k))
Console.WriteLine(k.j);
else
Console.WriteLine("ERROR ERRROR ERROR");
}
}
Run Code Online (Sandbox Code Playgroud)
并将您的修改static void Main(string[] args)
为:
static void Main(string[] args)
{
Program p = new Program();
p.fun1();
GC.Collect();
p.fun2();
Console.Read();
}
Run Code Online (Sandbox Code Playgroud)
好的,让我们完成这些更改
我们正在使用(您也可以使用WeakReference)
如果 GC 现在遇到我们的对象,他找不到 StrongReference 所以可以收集它WeakReference<T>
现在GC.Collect()
你需要调用它,因为它迫使 GC 完成他的工作(现在此时此刻)
请记住,就像我之前告诉过你的那样,IDisposable会在销毁对象之前从 GC 中调用(AFAIK),因此有一个地方可以放置在对象被销毁之前需要完成的所有内容
归档时间: |
|
查看次数: |
603 次 |
最近记录: |