OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
MemoryWatchdog.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.Linq;
31 using System.Reflection;
32 using System.Threading;
33 using log4net;
34 
35 namespace OpenSim.Framework.Monitoring
36 {
40  public static class MemoryWatchdog
41  {
42 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 
47  public static bool Enabled
48  {
49  get { return m_enabled; }
50  set
51  {
52 // m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
53 
54  if (value && !m_enabled)
55  UpdateLastRecord(GC.GetTotalMemory(false), Util.EnvironmentTickCount());
56 
57  m_enabled = value;
58  }
59  }
60  private static bool m_enabled;
61 
65  public static double AverageHeapAllocationRate
66  {
67  get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; }
68  }
69 
73  public static double LastHeapAllocationRate
74  {
75  get { if (m_samples.Count > 0) return m_samples.Last(); else return 0; }
76  }
77 
85  private static int m_maxSamples = 24;
86 
90  private static int m_lastUpdateTick;
91 
95  private static long m_lastUpdateMemory;
96 
100 // private static double m_churnRatePerMillisecond;
101 
105  private static Queue<double> m_samples = new Queue<double>(m_maxSamples);
106 
107  public static void Update()
108  {
109  int now = Util.EnvironmentTickCount();
110  long memoryNow = GC.GetTotalMemory(false);
111  long memoryDiff = memoryNow - m_lastUpdateMemory;
112 
113  if (memoryDiff >= 0)
114  {
115  if (m_samples.Count >= m_maxSamples)
116  m_samples.Dequeue();
117 
118  double elapsed = Util.EnvironmentTickCountSubtract(now, m_lastUpdateTick);
119 
120  // This should never happen since it's not useful for updates to occur with no time elapsed, but
121  // protect ourselves from a divide-by-zero just in case.
122  if (elapsed == 0)
123  return;
124 
125  m_samples.Enqueue(memoryDiff / (double)elapsed);
126  }
127 
128  UpdateLastRecord(memoryNow, now);
129  }
130 
131  private static void UpdateLastRecord(long memoryNow, int timeNow)
132  {
133  m_lastUpdateMemory = memoryNow;
134  m_lastUpdateTick = timeNow;
135  }
136  }
137 }