lucenenet-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Digy (JIRA)" <j...@apache.org>
Subject [jira] Commented: (LUCENENET-106) Lucene.NET (Revision: 603121) is leaking memory
Date Mon, 19 Jan 2009 21:04:59 GMT

    [ https://issues.apache.org/jira/browse/LUCENENET-106?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12665231#action_12665231
] 

Digy commented on LUCENENET-106:
--------------------------------

Hi Eyal,

To simplify the code, I'd suggest another variant of your code:  Instead of implementing whole
IDictionary, inheriting from Hashtable and overriding necessary methods only.

A sample code is below. The only method which is different is "GetEnumerator"

{code}
    public class WeakHashTable : Hashtable
    {
        class WeakComparer : IEqualityComparer
        {
            static WeakComparer _instance;

            static WeakComparer()
            {
                _instance = new WeakComparer();
            }

            bool IEqualityComparer.Equals(object x, object y)
            {
                if (x == y)
                    return true;

                if (x is WeakKey)
                {
                    x = ((WeakKey)x).Target;
                    if (x == null)
                        return false;
                }

                if (y is WeakKey)
                {
                    y = ((WeakKey)y).Target;
                    if (y == null)
                        return false;
                }

                return x.Equals(y);
            }

            int IEqualityComparer.GetHashCode(object obj)
            {
                return obj.GetHashCode();
            }

            public static WeakComparer Instance
            {
                get
                {
                    return _instance;
                }
            }
        }

        class WeakKey : WeakReference
        {
            int hashCode;

            public WeakKey(object key)
                : base(key)
            {
                if (key == null)
                    throw new ArgumentNullException("key");

                hashCode = key.GetHashCode();
            }

            public override int GetHashCode()
            {
                return hashCode;
            }
        }
        
        WeakReference collectableObject = new WeakReference(new Object());

        public WeakHashTable() : base(WeakComparer.Instance)
        {
        }

        private void CleanIfNeeded()
        {
            if (collectableObject.Target == null)
            {
                Clean();
                collectableObject = new WeakReference(new Object());
            }
        }

        private void Clean()
        {
            ArrayList keysToDelete = new ArrayList();
            foreach (WeakKey wtk in base.Keys)
            {
                if (!wtk.IsAlive)
                {
                    keysToDelete.Add(wtk);
                }
            }

            foreach (WeakKey wtk in keysToDelete)
                base.Remove(wtk);
        }

        
        public override void Add(object key, object value)
        {
            CleanIfNeeded();
            base.Add(new WeakKey(key), value);
        }

        public override IDictionaryEnumerator GetEnumerator()
        {
            System.Collections.Hashtable dictEntires = new Hashtable();

            foreach (WeakKey key in base.Keys)
            {
                object realKey = key.Target;
                if (realKey != null)
                    dictEntires.Add( realKey,base[realKey] );
            }
            return dictEntires.GetEnumerator();
        }

        public override ICollection Keys
        {
            get
            {
                ArrayList keys = new ArrayList(Count);
                foreach (WeakKey key in base.Keys)
                {
                    object realKey = key.Target;
                    if (realKey != null)
                        keys.Add(realKey);
                }
                return keys;
            }
        }
        
        public override object this[object key]
        {
            get
            {
                return base[key];
            }
            set
            {
                CleanIfNeeded();
                base[new WeakKey(key)] = value;
            }
        }

        public override void CopyTo(Array array, int index)
        {
            int arrayIndex = index;
            foreach (object key in Keys)
            {
                DictionaryEntry de = new DictionaryEntry(key, this[key]);
                array.SetValue(de, arrayIndex++);
            }
        }

        public override int Count
        {
            get
            {
                CleanIfNeeded();
                return base.Count;
            }
        }
    }

{code}


DIGY


> Lucene.NET (Revision: 603121) is leaking memory
> -----------------------------------------------
>
>                 Key: LUCENENET-106
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-106
>             Project: Lucene.Net
>          Issue Type: Bug
>         Environment: .NET 2.0
>            Reporter: Anton K.
>            Assignee: Digy
>            Priority: Critical
>         Attachments: DIGY-FieldCacheImpl.patch, Digy.rar, luceneSrc_memUsage.patch, Paches
for v2.3.1.rar, WeakHashTable v2.patch, WeakHashTable v2.patch, WeakHashTable+FieldCacheImpl.rar,
WeakHashTable_ep.zip, WeakHashTable_tj.zip, WeakReferences.rar
>
>
> readerCache Hashtable field (see FieldCacheImpl.cs) never releases some hash items that
have closed IndexReader object as a key. So a lot of Term instances are never released.
> Java version of Lucene uses WeakHashMap and therefore doesn't have this problem.
> This bug can be reproduced only when Sort functionality used during search. 
> See following link for additional information.
> http://www.gossamer-threads.com/lists/lucene/java-user/55681
> Steps to reproduce:
> 1)Create index
> 2) Modify index by IndexWiter; Close IndexWriter
> 3) Use IndexSearcher for searching with Sort; Close InexSearcher
> 4) Go to step 2
> You'll get OutOfMemoryException after some time of running this algorithm.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message