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

如果用代码表现,则是:

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. Java代码通过API操作HBase的最佳实践

    HBase提供了丰富的API.这使得用Java连接HBase非常方便. 有时候大家会使用HTable table=new HTable(config,tablename);的方式来实例化一个HTabl ...

  2. SpringBoot自定义序列化的使用方式--WebMvcConfigurationSupport

    场景及需求: 项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串. 例如: [     {         "id": 1,      ...

  3. unity, Collider2D.bounds的一个坑

    Note that this will be an empty bounding box if the collider is disabled or the game object is inact ...

  4. js两个日期相减

    function dateHanle(d1,d2){ if(Date.parse(d1) - Date.parse(d2)==0) { console.log("d1等于d2"); ...

  5. iOS数据库离线缓存思路和网络层封装

    一直想总结一下关于iOS的离线数据缓存的方面的问题,然后近期也简单的对AFN进行了再次封装.全部想把这两个结合起来写一下.数据展示型的页面做离线缓存能够有更好的用户体验,用户在离线环境下仍然能够获取一 ...

  6. 【R】R语言常用函数

    R语言常用函数 基本 一.数据管理vector:向量 numeric:数值型向量 logical:逻辑型向量character:字符型向量 list:列表 data.frame:数据框c:连接为向量或 ...

  7. 开发集成工具MyEclipse中Outline的问题

    序言 不懂的多查,越查就越显得自己的无知,越发现大神的存在,可能相对于我来说是大神,在他那个高度,就觉得自己很菜,这些都正常,最值得敬佩的是,比你厉害的人,还比你更努力,那自己还有什么理由不努力呢,如 ...

  8. 【Unity】6.6 Random类

    分类:Unity.C#.VS2015 创建日期:2016-04-20 一.简介 Unity引擎提供的Random类可以用来生成随机数.随机点或旋转角度. 1.成员变量 seed:设置用于随机数生成器的 ...

  9. JAVA中转义字符

    JAVA中转义字符 2010年08月11日 星期三 上午 12:22 JAVA中转义字符: 1.八进制转义序列:\ + 1到3位5数字:范围'\000'~'\377'       \0:空字符 2.U ...

  10. 【MyBean调试笔记】关于单元的释放顺序

    [概述] DEMO提交人:惠商软件  2508696439 问题描述:MDIConsole, DEMO如果Forms单元引用顺序放在mybean.console.pas文件之后如下图所示时: 创建同一 ...