111,120
社区成员
发帖
与我相关
我的任务
分享person p1 = new person();
p1.Name = "Tam";
WeakReference wkr = new WeakReference(p1);
p1 = null;
GC.Collect(); // 强制进行垃圾回收
object wP1 = wkr.Target;
if (wP1 != null)
{
Console.WriteLine(((person)wP1).Name);
}
else
{
Console.WriteLine("对象已被回收");
}
Console.ReadKey();
}
}
class person
{
public string Name { get; set; }
}
因为我也没搞懂gc.collection到底是怎么执行的,尤其还可以指定回收几代
emoji酷啊,这team里要是有几个女生和伪娘,一堆emoji,code review很艰难的说!
coreclr也是微软的,它和咱们用的标准clr有啥区别?
关于GC.Collect不同行为的问题,我觉得如果可以获取编译时的完整flags,就应该可以看出区别吧?不过照你这么说,在MSIL这步,大家很可能都是一样的,只是到了JIT的时候才出现的不同结果?
LINQ你揍不要再提了,越描越黑啦!
MS不是保证说不会影响编译后结果吗?
移植到coreclr?这是毛意思?夸平台到linux吗?mono不好使吗?MS不是自己也要搞吗?
自己写GC?给你的应用写一个不难,写一个generic的,揍呵呵了!
成了,给你写了这么多,别说我们不鼓励你技术讨论。
你还蛮特别的,.NET版像你这样肯吊书袋的不多!
.net版一堆的MVP,不知道MCSD有几个!
GC 对待有析构器的对象是不一样的(之前提到的析构队列机制,有析构会导致更慢的回收,一般除非直接引用了非托管资源,否则不应该使用析构),所以这里不能放在一起比较。
无论如何,讨论技术也比空洞和讽刺的评论有意义。你也了解底层知识,应该也明白探索精神有多么重要。大部分情况下不需要手动gc,但是它绝对值得讨论。你是说这个 API 暴露出来就是给挫人用的么?我也很想了解下需要“有板有眼”讨论的是什么问题,可否举例对比下意义。
你可以试试 Ref12 插件,一点不费劲。那个是源码,有注释和被编译器去掉的代码,比反编译的好。(顺便安利下 EmojiVS 这个插件~)
当然是非托管的,它最后调用到了 gc.cpp 里面的 GCHeap::GarbageCollect (int generation, BOOL low_memory_p, int mode)
coreclr 的结果倒是和 clr 一致。
难道不是么?要不然解释下这么说价值何在。
找了台 vs2012 的机器试验,确实debug下也可以回收。进一步发现,只要不使用 RyuJIT 就是和之前版本一致的结果(#16 说的 clr 2 和 clr 4 不一致的结果也是 RyuJIT 导致的)。那么现在看起来,是 LZ 的情况最为奇怪,Release 都不能回收就不太正常了。
这里还有个坑,如果 var p1 = new person { Name = "Tam" }; 这么写的话,会产生一个看不见的临时变量引用这个对象,后面 p1 = null; 不会作用于这个临时变量,也能导致 Debug 下无法回收。
我这么热衷这个问题一方面是因为有东西要移植到 coreclr,需要深入了解新的 .net 开源体系;另一方面是因为原来看过 LuaJIT 的 新 GC 设计,现在又被勾起了写个GC玩玩的冲动。其实需要说的有 #16 就够了,后面的权当废话吧。[/quote]
顺便说一句,我用的是VS2013版。
这个问题我一直弄不明白真正原因,姑且只能相信是GC回收的代码即使写出来也不是立刻能够全部将垃圾回收掉这个说法了
费这么大劲儿,给我看这个不就结了!
https://msdn.microsoft.com/en-us/library/bb384155(v=vs.110).aspx
你说的好玩的事真的发生了:在我笔记本上的vs2013里,debug环境下(target: 4.5, runtime:4.0),怎么写都可以回收。为毛呢?你自己去研究吧!哦对了,_Collect的实现好想木有给啊!非托管代码吧?要不,你看看ML怎么说?
对了,我还去看了一眼mcs的结果,很可悲,咱们这写的这些垃圾一律木用。
我最后的话更没价值?那你来解释下,为毛会有这种情况?给咱来点有价值的!
既然MS划好了圈圈,安心在里面玩揍是了。托管的世界多美好啊!
class GarbageCollect
{
public static void ForceCollect()
{
object obj = new object();
WeakReference wr=new WeakReference(obj);
obj=null;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
object wP1 = wr.Target;
if (wP1 != null)
{
Console.WriteLine("obj is still alive");
}
else
{
Console.WriteLine("gc is done");
}
}
}
了解了GC的概念,知道了generation,big object heap等,貌似对这个问题也木有帮助是吧?在CLR这个level还要反编译ML出来说明问题,你们也太C了!既然MS划好了圈圈,安心在里面玩揍是了。托管的世界多美好啊!
[quote=引用 11 楼 sp1234 的回复:] 如果你看到一篇文章上说“DEBUG下就不会在当前方法完毕前释放对象,而RELEASE下就会在当前方法执行完毕钱释放对象”,那么你看我上面对代码的修改就能知道了,这篇文章写错了!
用多线程的话是结果是被回收了。这是GC回收机制的不确定性,还是因为线程的问题?如果你看到一篇文章上说“DEBUG下就不会在当前方法完毕前释放对象,而RELEASE下就会在当前方法执行完毕钱释放对象”,那么你看我上面对代码的修改就能知道了,这篇文章写错了!
我尝试在Release模式下运行,但是结果还是和Debug一样。用多线程的话是结果是被回收了。这是GC回收机制的不确定性,还是因为线程的问题?
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
你使用多线程看到了回收的结果,不要理解错了。那是因为方法中代码改变了,会影响到 jit 计算的生命周期,而不是因为需要等待 GC.Collect 执行。你可以试验,仅仅把测试是否回收的代码移到另一个方法里就能改变结果。我尝试在Release模式下运行,但是结果还是和Debug一样。用多线程的话是结果是被回收了。这是GC回收机制的不确定性,还是因为线程的问题?
