一直想做这么一个测试,人和手的测试。类型"人"有一个属性"手",需要"手"也可以读取"人"的数据。则"手"下面也有一个属性"人"。

如果用代码表现,则是:

public class Class人
{
private Class手 _手;
public Class手 手 { get { return _手; } set { _手 = value; } } private Class脚 _脚;
public Class脚 脚 { get { return _脚; } set { _脚 = value; } } private Class脑 _脑;
public Class脑 脑 { get { return _脑; } set { _脑 = value; } } public Class人()
{
_手 = new Class手(this);
_脚 = new Class脚(this);
_脑 = new Class脑(this);
}
} public class Class手
{
private Class人 _人;
public Class人 人 { get { return _人; } } public Class手(Class人 one)
{
_人 = one;
}
}

这样可以实现 人.手 和 手.人 的相互访问。

我的疑问是:人和手之间的这种相互强引用会不会造成资源一直处于被引用状态,不能被回收,从而导致内存泄漏?

于是做了一个测试,测试的思路是:建立两个相互引用的类A/B,其中A含有B,B只需要访问A。A构造的时候会占用大量的内存。执行的时候,在函数以外定义变量C来承装List<A>并初始化。在函数内,重复的生成A的实例并放到C中。在某个时段,将C清空,强制垃圾回收,看A的集合占用的内存是否会释放。代码如下:

public class Class人
{
private Class手 _手;
public Class手 手 { get { return _手; } set { _手 = value; } }
public List<string> Data;
public Class人()
{
_手 = new Class手(this);
Data = new List<string>();
for (int i = ; i < ; i++)
Data.Add(Enumerable.Range(, ).Select(x => x.ToString()).Aggregate((x, y) => x + y));
}
} public class Class手
{
private Class人 _人;
public Class人 人 { get { return _人; } } public Class手(Class人 one)
{
_人 = one;
}
}

执行代码:

static List<Class人> data = new List<Class人>();
static void Main(string[] args)
{
for (int i = ; i < ; i++)
data.Add(new Class人()); Console.WriteLine("ok");
var read = Console.ReadLine();
if (read == "Y")
{
data.Clear();
GC.Collect();
} Console.ReadKey();
}

测试的结果如下:

1. 在启动程序前,内存占用61%;

2. 启动后,"ok"前,也就是生成Class人的实例集合后,内存占用68%。

3.1 如果此时输入"Y",立刻清空承载的data变量,并进行垃圾回收,内存占用返回至62%,关闭程序后返回61%。

3.2  如果此时输入"Y",只是清空data,不执行垃圾回收,内存还停留在68%,关闭程序后直接返回61%(参考3.1,等到下一个垃圾回收时,应该会清空至62%)

由此可以推出,即使数据里面,class人和class手相互引用了,但没有其他数据调用时,垃圾回收机制仍然会将其视为垃圾然后回收。

本来想通过弱引用处理这种相互引用的,通过测试后,感觉不用。以下贴出我查询到的一些声音:

".NET不是使用引用计数器的方法"

".NET处理循环引用不是通过弱引用来实现的,而是通过遍历对象,释放无法访问的对象来完成的"

由于对.net的垃圾回收机制研究得不通透,所以给不了一些原理上的解释,如果有大牛知道这一部分,欢迎给我留言。

如果测试结果有误,请严肃纠正。

转载请注明出处:http://www.cnblogs.com/icyJ

.net 循环引用是否会造成内存泄漏的更多相关文章

  1. 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug

    前言: 话说昨晚还是前晚,写了一篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上) 文章写到最后时,多了很多莫名奇妙的问题!!! 为了解决了这些莫名奇妙的问题,我又战斗了2 ...

  2. 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(下)- block中任性用self

    前言: 在处理完框架内存泄漏的问题后,见上篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug 发现业务代码有一个地方的内存没释放,原因很也简单: ...

  3. [转] weak_ptr解决shared_ptr环状引用所引起的内存泄漏

    http://blog.csdn.net/liuzhi1218/article/details/6993135 循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引 ...

  4. weak_ptr解决shared_ptr环状引用所引起的内存泄漏[转]

    转载:http://blog.csdn.net/liuzhi1218/article/details/6993135 循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理 ...

  5. echarts配合循环计时器等出现的内存泄漏

    echarts是百度的一个图表插件,确实好用美观. 之前实习接触到的页面大多是下面这种调用方式 var chart=echarts.init(document.getElementById(dom)) ...

  6. 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上)

    前言: 好久没写文章了,最近先是重构IT恋.又重写IT恋中. Sagit框架也不断的更新,调整,现在感觉已完美了了相当的多. 今天不写教程,先简单分享一下技术内容. 1:见Block必有:#defin ...

  7. JavaScript的闭包和内存泄漏问题

    闭包 http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html JavaScript中必须提到的功能最强大的抽象 ...

  8. JavaScript 中的内存泄漏

    JavaScript 中的内存泄漏 JavaScript 是一种垃圾收集式语言,这就是说,内存是根据对象的创建分配给该对象的,并会在没有对该对象的引用时由浏览器收回.JavaScript 的垃圾收集机 ...

  9. <转>Python的内存泄漏及gc模块的使用分析

    一般来说在 Python 中,为了解决内存泄漏问题,采用了对象引用计数,并基于引用计数实现自动垃圾回收.由于Python 有了自动垃圾回收功能,就造成了不少初学者误认为自己从此过上了好日子,不必再受内 ...

随机推荐

  1. 第一篇:初识ASP.NET控件开发_第一节:控件类及其继承关系

    1)System.Web.UI.Control(以下简称Control) Control 类是包括自定义控件.用户控件和页在内的所有 ASP.NET 服务器控件的基类..定义由所有 ASP.NET 服 ...

  2. uiautomatorviewer 查看元素新思路

    用adb 命令把图片和uix获取出来,再导入uiautomatorviewer adb shell uiautomator dump /data/local/tmp/uidump.uixadb pul ...

  3. 【转】在一个Job中同时写入多个HBase的table

    在进行Map/Reduce时,有的业务需要在一个job中将数据写入到多个HBase的表中,下面是实现方式. 原文地址:http://lookfirst.com/2011/07/hbase-multit ...

  4. rocketmq 学习记录-2

    产品选型 我们在进行中间件选型时,一般都是通过下面几点来进行产品选型的: 1.性能 2.功能支持程度 3.开发语言(团队中是否有成员熟悉此中间件的开发语言,市场上此种语言的开发人员是否好招) 4.有多 ...

  5. ios处理键盘

    #pragma mark - Keyboard - (void)addKeyboardNoti { [[NSNotificationCenter defaultCenter] addObserver: ...

  6. ASP.NET MVC做的微信WEBAPP中调用微信JSSDK扫一扫

    今天做一个项目,是在微信上用的,微信WEB APP,里面用到了调用手机摄像头扫一扫二维码的功能,记得以前某个项目里写有的,但是找不到之前那个项目源码了,想复制粘贴也复制不了了,只好对着微信的那个开发文 ...

  7. Atitit 图像处理类库 halcon11  安装与环境搭建attilax总结

    Atitit 图像处理类库 halcon11  安装与环境搭建attilax总结 正常安装软件,安装前请先退出其它一切正在运行的程序. 先安装halcon-10.0-windows.exe.安装完成后 ...

  8. MyEclipse中设置jsp页面为默认utf-8编码

    转自:http://www.cnblogs.com/xdp-gacl/p/3496161.html 在MyEclispe中创建Jsp页面,Jsp页面的默认编码是“ISO-8859-1”,如下图所示: ...

  9. lua 创建listview

    只要是新的聊天对象就创建一个新的listview local name = tolua.cast(UIHelper:seekWidgetByName(self.nameItem, "name ...

  10. iOS正则表达式的使用案例-富文本

    富文本(正则表达式) 一.新建工程导入图片 二 实现方式一(缺点是只能解决一个图片的替换) _myLabel.font = [UIFont systemFontOfSize:15]; //@" ...