.net 循环引用是否会造成内存泄漏
一直想做这么一个测试,人和手的测试。类型"人"有一个属性"手",需要"手"也可以读取"人"的数据。则"手"下面也有一个属性"人"。
如果用代码表现,则是:
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 循环引用是否会造成内存泄漏的更多相关文章
- 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug
前言: 话说昨晚还是前晚,写了一篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上) 文章写到最后时,多了很多莫名奇妙的问题!!! 为了解决了这些莫名奇妙的问题,我又战斗了2 ...
- 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(下)- block中任性用self
前言: 在处理完框架内存泄漏的问题后,见上篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug 发现业务代码有一个地方的内存没释放,原因很也简单: ...
- [转] weak_ptr解决shared_ptr环状引用所引起的内存泄漏
http://blog.csdn.net/liuzhi1218/article/details/6993135 循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引 ...
- weak_ptr解决shared_ptr环状引用所引起的内存泄漏[转]
转载:http://blog.csdn.net/liuzhi1218/article/details/6993135 循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理 ...
- echarts配合循环计时器等出现的内存泄漏
echarts是百度的一个图表插件,确实好用美观. 之前实习接触到的页面大多是下面这种调用方式 var chart=echarts.init(document.getElementById(dom)) ...
- 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上)
前言: 好久没写文章了,最近先是重构IT恋.又重写IT恋中. Sagit框架也不断的更新,调整,现在感觉已完美了了相当的多. 今天不写教程,先简单分享一下技术内容. 1:见Block必有:#defin ...
- JavaScript的闭包和内存泄漏问题
闭包 http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html JavaScript中必须提到的功能最强大的抽象 ...
- JavaScript 中的内存泄漏
JavaScript 中的内存泄漏 JavaScript 是一种垃圾收集式语言,这就是说,内存是根据对象的创建分配给该对象的,并会在没有对该对象的引用时由浏览器收回.JavaScript 的垃圾收集机 ...
- <转>Python的内存泄漏及gc模块的使用分析
一般来说在 Python 中,为了解决内存泄漏问题,采用了对象引用计数,并基于引用计数实现自动垃圾回收.由于Python 有了自动垃圾回收功能,就造成了不少初学者误认为自己从此过上了好日子,不必再受内 ...
随机推荐
- vue 关于deep watch / computed 监听不到 vuex state 对象变化的的问题
简而言之,如果vuex state 中是一个对象 {},那么监听就会有问题.先给出解决方案: // 超简易拷贝(如果是深拷贝还多此一举把get/set拷贝进去了,所以用简易拷贝即可) let __VA ...
- python appium 有道云笔记分享文章到qq
有道云添加一个笔记,笔记的title为aff 使用appium 把这篇文章分享到qq,前提是android里面有登录qq Python代码 from appium import webdriver i ...
- 全相FFT
作者:桂. 时间:2017-12-02 23:29:48 链接:http://www.cnblogs.com/xingshansi/p/7956491.html 一.相位提取 以正弦信号为例,x = ...
- JDK1.5新特性,基础类库篇,集合框架(Collections)
集合框架在JDK1.5中增强特性如下: 一. 新语言特性的增强 泛型(Generics)- 增加了集合框架在编译时段的元素类型检查,节省了遍历元素时类型转换代码量. For-Loop循环(Enhanc ...
- 关于ios7的适配问题
过年回来一直搞ios7的项目适配,也算是有些眉目. 方法一:直接动用Window #if __IPHONE_OS_VERSION_MAX_ALLOWED>=__IPHONE_7_0 [appli ...
- ios开发中的一些小技巧
1.如果在程序中想对某张图片进行处理的话(得到某张图片的一部分)可一用以下代码: UIImage *image = [UIImage imageNamed:filename]; CGImageRe ...
- android 通过命令行启动Apk
几个启动指定程序activity的例子 Music 和 Video(音乐和视频)的启动方法为: # am start -n com.android.music/com.android.music.Mu ...
- 每日英语:The Risks of Big Data for Companies
Big data. It's the latest IT buzzword, and it isn't hard to see why. The ability to parse more infor ...
- Java 编程下正则表达式判断字符串是否包含中文
package cn.sunzn.demo; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ...
- 用ubuntu的grpb2引导Remix OS或Phoenix OS
Remix OS游戏版,这里下载:http://youxi.jide.com/ 安装简单.我这里要解决的是安装后用ubunu的grub2菜单去引导它. 方法如下: 进入ubuntu系统里修改其grub ...