Esempio n. 1
0
        /*
         * Non-recursive version of object descend. this consumes more memory than recursive in-depth
         * traversal but prevents stack overflows on long chains of objects
         * or complex graphs (a max. recursion depth on my machine was ~5000 objects linked in a chain
         * so not too much).
         */

        private static long MeasureObjectSize(object root)
        {
            // Objects seen so far.
            IdentityHashSet <object> seen = new IdentityHashSet <object>();
            // Class cache with reference Field and precalculated shallow size.
            HashMap <Type, ClassCache> classCache = new HashMap <Type, ClassCache>();
            // Stack of objects pending traversal. Recursion caused stack overflows.
            Stack <object> stack = new Stack <object>();

            stack.Push(root);

            long totalSize = 0;

            while (stack.Count > 0)
            {
                object ob = stack.Pop();

                if (ob == null || seen.Contains(ob))
                {
                    continue;
                }
                seen.Add(ob);

                Type obClazz = ob.GetType();
                if (obClazz.IsArray)
                {
                    /*
                     * Consider an array, possibly of primitive types. Push any of its references to
                     * the processing stack and accumulate this array's shallow size.
                     */
                    long  size  = NUM_BYTES_ARRAY_HEADER;
                    Array array = (Array)ob;
                    int   len   = array.Length;
                    if (len > 0)
                    {
                        Type componentClazz = obClazz.GetElementType();
                        if (componentClazz.IsPrimitive)
                        {
                            size += (long)len * PrimitiveSizes[componentClazz];
                        }
                        else
                        {
                            size += (long)NUM_BYTES_OBJECT_REF * len;

                            // Push refs for traversal later.
                            for (int i = len; --i >= 0;)
                            {
                                object o = array.GetValue(i);
                                if (o != null && !seen.Contains(o))
                                {
                                    stack.Push(o);
                                }
                            }
                        }
                    }
                    totalSize += AlignObjectSize(size);
                }
                else
                {
                    /*
                     * Consider an object. Push any references it has to the processing stack
                     * and accumulate this object's shallow size.
                     */
                    try
                    {
                        ClassCache cachedInfo = classCache[obClazz];
                        if (cachedInfo == null)
                        {
                            classCache[obClazz] = cachedInfo = CreateCacheEntry(obClazz);
                        }

                        foreach (FieldInfo f in cachedInfo.ReferenceFields)
                        {
                            // Fast path to eliminate redundancies.
                            object o = f.GetValue(ob);
                            if (o != null && !seen.Contains(o))
                            {
                                stack.Push(o);
                            }
                        }

                        totalSize += cachedInfo.AlignedShallowInstanceSize;
                    }
                    catch (Exception e)
                    {
                        // this should never happen as we enabled setAccessible().
                        throw new Exception("Reflective field access failed?", e);
                    }
                }
            }

            // Help the GC (?).
            seen.Clear();
            stack.Clear();
            classCache.Clear();

            return(totalSize);
        }
Esempio n. 2
0
        /*
         * Non-recursive version of object descend. this consumes more memory than recursive in-depth
         * traversal but prevents stack overflows on long chains of objects
         * or complex graphs (a max. recursion depth on my machine was ~5000 objects linked in a chain
         * so not too much).
         */

        private static long MeasureObjectSize(object root)
        {
            // Objects seen so far.
            IdentityHashSet <object> seen = new IdentityHashSet <object>();
            // Class cache with reference Field and precalculated shallow size.
            IDictionary <Type, ClassCache> classCache = new JCG.Dictionary <Type, ClassCache>(IdentityEqualityComparer <Type> .Default);
            // Stack of objects pending traversal. Recursion caused stack overflows.
            Stack <object> stack = new Stack <object>();

            stack.Push(root);

            long totalSize = 0;

            while (stack.Count > 0)
            {
                object ob = stack.Pop();

                if (ob == null || seen.Contains(ob))
                {
                    continue;
                }
                seen.Add(ob);

                Type obClazz = ob.GetType();
                // LUCENENET specific - .NET cannot return a null type for an object, so no need to assert it
                if (obClazz.Equals(typeof(string)))
                {
                    // LUCENENET specific - we can get a closer estimate of a string
                    // by using simple math. Reference: http://stackoverflow.com/a/8171099.
                    // This fixes the TestSanity test.
                    totalSize += (2 * (((string)ob).Length + 1));
                }
                if (obClazz.IsArray)
                {
                    /*
                     * Consider an array, possibly of primitive types. Push any of its references to
                     * the processing stack and accumulate this array's shallow size.
                     */
                    long  size  = NUM_BYTES_ARRAY_HEADER;
                    Array array = (Array)ob;
                    int   len   = array.Length;
                    if (len > 0)
                    {
                        Type componentClazz = obClazz.GetElementType();
                        if (componentClazz.IsPrimitive)
                        {
                            size += (long)len * primitiveSizes[componentClazz];
                        }
                        else
                        {
                            size += (long)NUM_BYTES_OBJECT_REF * len;

                            // Push refs for traversal later.
                            for (int i = len; --i >= 0;)
                            {
                                object o = array.GetValue(i);
                                if (o != null && !seen.Contains(o))
                                {
                                    stack.Push(o);
                                }
                            }
                        }
                    }
                    totalSize += AlignObjectSize(size);
                }
                else
                {
                    /*
                     * Consider an object. Push any references it has to the processing stack
                     * and accumulate this object's shallow size.
                     */
                    try
                    {
                        if (!classCache.TryGetValue(obClazz, out ClassCache cachedInfo) || cachedInfo == null)
                        {
                            classCache[obClazz] = cachedInfo = CreateCacheEntry(obClazz);
                        }

                        foreach (FieldInfo f in cachedInfo.ReferenceFields)
                        {
                            // Fast path to eliminate redundancies.
                            object o = f.GetValue(ob);
                            if (o != null && !seen.Contains(o))
                            {
                                stack.Push(o);
                            }
                        }

                        totalSize += cachedInfo.AlignedShallowInstanceSize;
                    }
                    catch (Exception e)
                    {
                        // this should never happen as we enabled setAccessible().
                        throw new Exception("Reflective field access failed?", e);
                    }
                }
            }

            // Help the GC (?).
            seen.Clear();
            stack.Clear();
            classCache.Clear();

            return(totalSize);
        }
Esempio n. 3
0
        public void Resume(Object eventTarget)
        {
            if (GuiThreadHelper.IsInGuiThread())
            {
                // Nothing to do
                return;
            }
            IEventTargetExtractor eventTargetExtractor = typeToEventTargetExtractorsDict.GetExtension(eventTarget.GetType());

            if (eventTargetExtractor == null)
            {
                return;
            }
            eventTarget = eventTargetExtractor.ExtractEventTarget(eventTarget);
            if (eventTarget == null)
            {
                return;
            }
            IdentityLinkedSet <WaitForResumeItem> freeLatchMap = null;

            try
            {
                PausedEventTargetItem pauseETI;
                listenersWriteLock.Lock();
                try
                {
                    IdentityLinkedMap <Object, PausedEventTargetItem> pausedTargets = this.pausedTargets;
                    pauseETI = pausedTargets.Get(eventTarget);
                    if (pauseETI == null)
                    {
                        throw new System.Exception("No pause() active for target " + eventTarget);
                    }
                    pauseETI.PauseCount--;
                    if (pauseETI.PauseCount > 0)
                    {
                        return;
                    }
                    pausedTargets.Remove(eventTarget);

                    IList <Object>               remainingPausedEventTargets    = EvaluatePausedEventTargets();
                    IdentityHashSet <Object>     remainingPausedEventTargetsSet = new IdentityHashSet <Object>();
                    Iterator <WaitForResumeItem> iter = waitForResumeSet.Iterator();
                    while (iter.MoveNext())
                    {
                        WaitForResumeItem pauseItem = iter.Current;
                        remainingPausedEventTargetsSet.AddAll(remainingPausedEventTargets);
                        remainingPausedEventTargetsSet.RetainAll(pauseItem.PendingPauses);

                        if (remainingPausedEventTargetsSet.Count == 0)
                        {
                            iter.Remove();
                            if (freeLatchMap == null)
                            {
                                freeLatchMap = new IdentityLinkedSet <WaitForResumeItem>();
                            }
                            freeLatchMap.Add(pauseItem);
                        }
                        remainingPausedEventTargetsSet.Clear();
                    }
                }
                finally
                {
                    listenersWriteLock.Unlock();
                }
            }
            finally
            {
                if (freeLatchMap != null)
                {
                    foreach (WaitForResumeItem wfrItem in freeLatchMap)
                    {
                        wfrItem.Latch.CountDown();
                    }
                    foreach (WaitForResumeItem wfrItem in freeLatchMap)
                    {
                        try
                        {
                            wfrItem.ResultLatch.Await();
                        }
                        catch (System.Exception e)
                        {
                            throw new System.Exception("Fatal state occured. This may result in a global deadlock", e);
                        }
                    }
                }
            }
        }