首页 新闻 会员 周边 捐助

求大侠 提供一个string驻留机制的实现

0
悬赏园豆:140 [已解决问题] 解决于 2012-12-25 17:03

需求:如有一个实体类如下

    public class User
    {
        public string Name { get; set; }

        public string Address { get; set; }
    }

现在我要 创建User对象, 如果 里面的字段完全相同,则认为是同一个对象,把引用指向之前那个相同的对象。

如100个User实例,里面有99个实例的Name和Address是相同的,那我 只要保持 两个对象的引用即可,而不用保持100份,这样的 就可以提高内存的使用。

这个有点像 string驻留机制, 现在想用这种方式 来实现普通的class对象。

现在 是否已经有相关 组件,或者提供思路实现, 谢谢各位!!

Qlin的主页 Qlin | 老鸟四级 | 园豆:2403
提问于:2012-12-25 11:39
< >
分享
最佳答案
0

用 Dictionary 来保存,key 设置为 Name + Address 就行了。

收获园豆:100
Launcher | 高人七级 |园豆:45050 | 2012-12-25 11:43

保存的话, 如 Dictionary static 静态变量,里面存储了值,

里面的对象 什么时候会成为垃圾,就是 哪些对象是垃圾 哪些不是,这个 怎么区分?不然 就越存越多了。

Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 12:11

@Qlin: 这不都是由你的需求来订的吗?我问你,你蓝子里有2个鸡蛋,你怎么区分哪个鸡蛋是坏的,那个鸡蛋是好的?

Launcher | 园豆:45050 (高人七级) | 2012-12-25 13:03

@Launcher: 

我想 实现 自己维持一个对象池,判断 哪些对象是垃圾,哪些不是? 难道 还要 这个对象池 外面 来调用 显示的删除?  那 字符串 是 怎么维护的,只要申明就是,不用管之前的

Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 13:15

@Qlin: 大哥,我很佩服你,因为我说的是程序自身是不知道如何管理对象生命周期的,这都需要你自己编写代码来实现,究竟是在你所谓的对象池外部来管理,还是在对象池的内部来管理,这不都是要你自己编代码来实现的吗?既然要你自己实现,当然是你最清楚到底该如何管理对象生命周期。我又不知道,我怎么可以帮你把代码写出来呢。

要不你先去看看 Cache 或者 ADO.NET ConnectionPool 的实现方式,当然这两者是有区别的,所以没法简单的用 Cache 来管理 DbConnection。

字符串驻留机制,那也是微软编写了代码实现的,不是凭空来的。

Launcher | 园豆:45050 (高人七级) | 2012-12-25 13:22

@Launcher: 

我不知道 怎么实现 内部自己管理, 能说一下 原理吗?或者 谈谈  字符串 是怎么实现的?介绍相关文章也行啊

Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 13:31

@Qlin: 你得先把你设想的如何使用对象池的代码写出来。因为字符串驻留机制和我们通常所说的对象池还是不一样的。同时,你还得告诉我,你要用什么标准来判断一个对象是“垃圾”?

Launcher | 园豆:45050 (高人七级) | 2012-12-25 13:33

@Launcher: 

原来以为可以 获取所有的引用数量,好像不能办到。现在 被你 这么一说,好多东西都没想到过。

现在 完全没思路了,大哥 网上  有相关的 现成的 实现 吗?

Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 13:42

@Qlin: Cache 的实现有很多,.Net memorycache 类可以使用引用来缓存,你可以翻看它的源码,基本也就是按照缓存策略,比如超过T时间没有被使用过(不管是否被引用)就逐出。ADO.NET 的 ConnectionPool 也是通过引用和弱引用来管理连接对象,其逐出策略是超过 T 时间(2-3分钟之间)后逐一释放没有被引用的连接对象(先转换为弱引用)直到连接池中的连接对象数为min pool size + 1.这些你都可以通过查看源码来找到实现代码。

所以这里有个很重要的概念,就是你所谓的“垃圾”,何为“垃圾”,在不同的实现下的定义是不一样的,比如没有被引用,T时间内(绝对时间和相对时间)没有被引用,T时间内(绝对时间和相对时间)没有使用等等,甚至还可以定义遇到 Address == "aaaaa" 时将对象标记为“垃圾”。

Launcher | 园豆:45050 (高人七级) | 2012-12-25 13:51

@Launcher: 

看了字符串的驻留,就想到 如果普通的引用对象也能这样,是不是可以,就有这种想法了。

呵呵 看来没那么简单。。     谢谢 指点!

Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 14:12

@Qlin: 做不到“字符串驻留机制”那样,因为这涉及到编译器和代码解释器,而这些是你无法控制的。如果能做到,那就不用你在这里提问了,微软早自己实现了(因为有字符串驻留机制在前)。

Launcher | 园豆:45050 (高人七级) | 2012-12-25 14:16

@Launcher: 

呵呵  也是,  如果真的能选择 这种驻留方式 创建对象 也蛮好的啊,主要是适合 那种 创建了 就不变的 对象。

Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 14:25
其他回答(2)
0

这个就是对象池。构造方法私有化。由类本身来负互责对象的新建。类里面写一个静态的Dictionary.其实是楼上说的。如果不存在就new 一个对象,如果存在,返回对象引用。基本不存在空间浪费。不过有一点点小的不足。就是对象的属性可能会改。比如add到集合中是key1,但程序运行过程中变成key2了。就存在信息不统一。可以考虑采用遍历比较的变法。效率不高。如果采用监听者模式,就有点复杂。你自己权衡吧。

收获园豆:15
angelshelter | 园豆:9914 (大侠五级) | 2012-12-25 13:02

哪里的 对象 怎么实现 自己管理呢? 比如有一个对象 成为垃圾了,自己 到时删除了,而不用外面 调用 来删除

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 13:16
0

给个例子:

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);
                   }
                }
            }
        }
收获园豆:25
chenping2008 | 园豆:9836 (大侠五级) | 2012-12-25 13:13

如果 有对象 是垃圾了, 只能 通过 提供一个方法,外面调用 删除这个对象吗? 能不能 这个集合里自己维护呢?

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 13:18

@Qlin: 那定义一个remove方法

支持(0) 反对(0) chenping2008 | 园豆:9836 (大侠五级) | 2012-12-25 13:38

@chenping2008: 

有没有 先进点的 实现方式? _users自己管理 里面的对象??

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 13:43

@Qlin: 再怎么先进也是一个程序,也是需要去调用的

支持(0) 反对(0) chenping2008 | 园豆:9836 (大侠五级) | 2012-12-25 13:44

@chenping2008: 

字符串 不是  不用管的吗? 他是 如何管理的

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-12-25 13:50
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册