需求:如有一个实体类如下
public class User { public string Name { get; set; } public string Address { get; set; } }
现在我要 创建User对象, 如果 里面的字段完全相同,则认为是同一个对象,把引用指向之前那个相同的对象。
如100个User实例,里面有99个实例的Name和Address是相同的,那我 只要保持 两个对象的引用即可,而不用保持100份,这样的 就可以提高内存的使用。
这个有点像 string驻留机制, 现在想用这种方式 来实现普通的class对象。
现在 是否已经有相关 组件,或者提供思路实现, 谢谢各位!!
用 Dictionary 来保存,key 设置为 Name + Address 就行了。
保存的话, 如 Dictionary static 静态变量,里面存储了值,
里面的对象 什么时候会成为垃圾,就是 哪些对象是垃圾 哪些不是,这个 怎么区分?不然 就越存越多了。
@Qlin: 这不都是由你的需求来订的吗?我问你,你蓝子里有2个鸡蛋,你怎么区分哪个鸡蛋是坏的,那个鸡蛋是好的?
@Launcher:
我想 实现 自己维持一个对象池,判断 哪些对象是垃圾,哪些不是? 难道 还要 这个对象池 外面 来调用 显示的删除? 那 字符串 是 怎么维护的,只要申明就是,不用管之前的
@Qlin: 大哥,我很佩服你,因为我说的是程序自身是不知道如何管理对象生命周期的,这都需要你自己编写代码来实现,究竟是在你所谓的对象池外部来管理,还是在对象池的内部来管理,这不都是要你自己编代码来实现的吗?既然要你自己实现,当然是你最清楚到底该如何管理对象生命周期。我又不知道,我怎么可以帮你把代码写出来呢。
要不你先去看看 Cache 或者 ADO.NET ConnectionPool 的实现方式,当然这两者是有区别的,所以没法简单的用 Cache 来管理 DbConnection。
字符串驻留机制,那也是微软编写了代码实现的,不是凭空来的。
@Launcher:
我不知道 怎么实现 内部自己管理, 能说一下 原理吗?或者 谈谈 字符串 是怎么实现的?介绍相关文章也行啊
@Qlin: 你得先把你设想的如何使用对象池的代码写出来。因为字符串驻留机制和我们通常所说的对象池还是不一样的。同时,你还得告诉我,你要用什么标准来判断一个对象是“垃圾”?
@Launcher:
原来以为可以 获取所有的引用数量,好像不能办到。现在 被你 这么一说,好多东西都没想到过。
现在 完全没思路了,大哥 网上 有相关的 现成的 实现 吗?
@Qlin: Cache 的实现有很多,.Net memorycache 类可以使用引用来缓存,你可以翻看它的源码,基本也就是按照缓存策略,比如超过T时间没有被使用过(不管是否被引用)就逐出。ADO.NET 的 ConnectionPool 也是通过引用和弱引用来管理连接对象,其逐出策略是超过 T 时间(2-3分钟之间)后逐一释放没有被引用的连接对象(先转换为弱引用)直到连接池中的连接对象数为min pool size + 1.这些你都可以通过查看源码来找到实现代码。
所以这里有个很重要的概念,就是你所谓的“垃圾”,何为“垃圾”,在不同的实现下的定义是不一样的,比如没有被引用,T时间内(绝对时间和相对时间)没有被引用,T时间内(绝对时间和相对时间)没有使用等等,甚至还可以定义遇到 Address == "aaaaa" 时将对象标记为“垃圾”。
@Launcher:
看了字符串的驻留,就想到 如果普通的引用对象也能这样,是不是可以,就有这种想法了。
呵呵 看来没那么简单。。 谢谢 指点!
@Qlin: 做不到“字符串驻留机制”那样,因为这涉及到编译器和代码解释器,而这些是你无法控制的。如果能做到,那就不用你在这里提问了,微软早自己实现了(因为有字符串驻留机制在前)。
@Launcher:
呵呵 也是, 如果真的能选择 这种驻留方式 创建对象 也蛮好的啊,主要是适合 那种 创建了 就不变的 对象。
这个就是对象池。构造方法私有化。由类本身来负互责对象的新建。类里面写一个静态的Dictionary.其实是楼上说的。如果不存在就new 一个对象,如果存在,返回对象引用。基本不存在空间浪费。不过有一点点小的不足。就是对象的属性可能会改。比如add到集合中是key1,但程序运行过程中变成key2了。就存在信息不统一。可以考虑采用遍历比较的变法。效率不高。如果采用监听者模式,就有点复杂。你自己权衡吧。
哪里的 对象 怎么实现 自己管理呢? 比如有一个对象 成为垃圾了,自己 到时删除了,而不用外面 调用 来删除
给个例子:
private static List<User> _users; private static readonly object _sync = new object(); public void CreateUser(string name, string address) { User user = new User(){ Name = name, Address=address }; lock (_sync) { if (_users.Count <= 0) { _users.Add(user); } else { User one = _users.FirstOrDefault(l => l.Address == address && l.Name == name); if (one == null) { _users.Add(user); } } } }
如果 有对象 是垃圾了, 只能 通过 提供一个方法,外面调用 删除这个对象吗? 能不能 这个集合里自己维护呢?
@Qlin: 那定义一个remove方法
@chenping2008:
有没有 先进点的 实现方式? _users自己管理 里面的对象??
@Qlin: 再怎么先进也是一个程序,也是需要去调用的
@chenping2008:
字符串 不是 不用管的吗? 他是 如何管理的