如何判断一个对象是否被回收了?

货郎大叔 2019-05-30 10:47:29
一个没有再使用的对象,GC会自动回收,那么,我如何知道一个对象被GC回收了呢?也就是说,有时候我可能无法判断某个对象是否在不用的时候是否还存在引用,我想知道GC回收没有,怎么才能知道呢?
...全文
708 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_43373360 2020-01-06
  • 打赏
  • 举报
回复 1
可以使用finalize方法,在类中重写后,当对象回收时就会调用finalize()方法了 https://segmentfault.com/q/1010000008702841
货郎大叔 2019-06-03
  • 打赏
  • 举报
回复
引用 1 楼 wanghui0380 的回复:
前贴已说,vs调试工具有“性能诊断”---其中截取快照,查看堆 windows的任务管理器也可以实时截取“dump”内存快照,同样你可以使用工具诊断这个dump 当然还有其他的工具,比如memprofile 至于代码,我们不从代码上看。因为我们不关心那“一个”代码,我们关心是整个程序的性能和稳定
vs调试工具上,好像只能看到整个内存的情况诶,能看到Person对象被回收了吗?
wanghui0380 2019-06-03
  • 打赏
  • 举报
回复
你这个例子也一样啊 方法A new 张三 +1 把b重新李四,张三-1,李四+1,。 --------------------------------------- 如果你这里故意丢外面,那么外面引用+1,如果这个能执行完那么他自己-1,如果这里永远占着,那么这里永远+1 方法A退出 李四-1 红色部分是可选,你没有红色部分,这里你看到了,无论张三,还是李四。出了方法体引用都是0
wanghui0380 2019-06-03
  • 打赏
  • 举报
回复
Button_Click方法都执行完了,方法内的临时变量自然要清除掉,因为外面没人用了。 如果你又在外面使用了,自然计数不会0,gc就不清了。 上个帖子已经给你展示过了,如果一个方法里,挂一个事件,而且这个事件还不立刻执行完(比如我把那个帖子里把sender故意存在一个list里,这个list会把计数+1,那么gc认为有人用,所以不清) 同样上个帖子也展示给你了,如果我不故意把sender保存,事件执行完毕,出了事件方法作用域,引用-1,为0就释放 其实就是 方法A用了+1,事件用了+1,list用了+1,方法A退出-1,事件A退出-1 你看到了,如果没有list,引用是0,如果有list引用是1
货郎大叔 2019-06-03
  • 打赏
  • 举报
回复
引用 11 楼 wanghui0380 的回复:
当然,你new了2个,但只看到一个。说明微软释放了一个对吧。
上面那幅图,我传错了。还是在wpf中来看看吧

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Person b = new Person("张三");
        b = new Person("李四");
    }
}
class Person
{
    string Name;
    public Person(string s)
    {
        Name = s;
    }
}
在Button的单击中,new了2个Person对象,但是在诊断工具中,一个Person对象都没有搜到,是不是意味着Person对象都被GC回收了。这里为什么要回收呢,第二个对象应该是存在的啊
wanghui0380 2019-06-03
  • 打赏
  • 举报
回复
当然,你new了2个,但只看到一个。说明微软释放了一个对吧。
wanghui0380 2019-06-03
  • 打赏
  • 举报
回复
9楼,本来就没回收啊 上个帖子已经说了,作用域。方法作用域,你还在main里阻塞着呢,他还在执行main方法呢,怎么释放。又没有using告诉他,也没有dispose他,微软当然不知道在这个方法后,还用不用 比如,你还可以写成 Person b = new Person("张三"); b = new Person("李四"); Console.ReadKey(); Console.write(b.Tostring());//你说微软到底应该在前面释放,还是不该在前面释放。
货郎大叔 2019-06-03
  • 打赏
  • 举报
回复
引用 7 楼 D56233577 的回复:
快照上可以搜索 Person,搜索不到代表被回收。

class Person
{
    string Name;
    public Person(string s)
    {
        Name = s;
    }
}
class Program
{
    static void Main(string[] args)
    {
        Person b = new Person("张三");
        b = new Person("李四");
        Console.ReadKey();
    }
}
类似于上面这种,有一个Person对象被回收了,有一个没有回收,在快照里面能搜出来 那按照你的说法,搜索不到代表被回收,那这里的Person对象就没有被回收哦
货郎大叔 2019-06-03
  • 打赏
  • 举报
回复
引用 7 楼 D56233577 的回复:
快照上可以搜索 Person,搜索不到代表被回收。
快照,"不可用"啊,能够搜出来,应该是被回收了吧
D56233577 2019-06-03
  • 打赏
  • 举报
回复
快照上可以搜索 Person,搜索不到代表被回收。
threenewbee 2019-06-01
  • 打赏
  • 举报
回复
WeakReference 了解一下 https://docs.microsoft.com/en-us/dotnet/api/system.weakreference?redirectedfrom=MSDN&view=netframework-4.8
mk_lucifer 2019-06-01
  • 打赏
  • 举报
回复
继承IDisposable 任何类只要继承该接口,一定会调用此接口,假设你对对象命名或有ID,假如叫张三, 那么一旦被调用,可以输出 ”张三 被释放“ ,或者其他任何形式,如果谁想直到她有没有释放,就查询有没有张三被释放这条记录。。。
正怒月神 2019-05-31
  • 打赏
  • 举报
回复
楼上说了,就不赘述了。
wanghui0380 2019-05-31
  • 打赏
  • 举报
回复
同样上个帖子之所以放了一个byte[] 也是这个意思,new一个对象自然是要分配这个byte[],GC释放一个对象,自然也要释放这个byte[] 所以你可以在“性能诊断”--进程内存实时图上,看到明显的new“内存增加”----- 释放"内存减少" 这种锯齿状的图形表现,同时“内存实时图”会用黄色三角箭头告诉你,那是GC强制释放的
wanghui0380 2019-05-31
  • 打赏
  • 举报
回复
前贴已说,vs调试工具有“性能诊断”---其中截取快照,查看堆 windows的任务管理器也可以实时截取“dump”内存快照,同样你可以使用工具诊断这个dump 当然还有其他的工具,比如memprofile 至于代码,我们不从代码上看。因为我们不关心那“一个”代码,我们关心是整个程序的性能和稳定

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧