Skip to content
Browse files

Extracted methods to get free/available memory into MemoryStatistics …

…class

and support getting free memory on Linux
  • Loading branch information...
1 parent 753f25e commit f3b8ca319adc0ad00b103abce3f156476094212b unknown committed with Tobias Grimm Feb 26, 2012
View
66 Raven.Database/Config/InMemoryRavenConfiguration.cs
@@ -16,7 +16,6 @@
using System.Threading;
using System.Threading.Tasks;
using System.Web;
-using Microsoft.VisualBasic.Devices;
using Raven.Abstractions.Data;
using Raven.Database.Extensions;
using Raven.Database.Server;
@@ -40,7 +39,7 @@ public InMemoryRavenConfiguration()
MaxNumberOfItemsToIndexInSingleBatch = Environment.Is64BitProcess ? 128*1024 : 64*1024;
InitialNumberOfItemsToIndexInSingleBatch = Environment.Is64BitProcess ? 512 : 256;
- AvailableMemoryForRaisingIndexBatchSizeLimit = Math.Min(768, GetTotalPhysicalMemoryMegabytes()/2);
+ AvailableMemoryForRaisingIndexBatchSizeLimit = Math.Min(768, MemoryStatistics.TotalPhysicalMemory/2);
MaxNumberOfParallelIndexTasks = 8;
Catalog = new AggregateCatalog(
@@ -254,11 +253,9 @@ private X509Certificate2 GetCertificate()
private int GetDefaultMemoryCacheLimitMegabytes()
{
- var totalPhysicalMemoryMegabytes = GetTotalPhysicalMemoryMegabytes();
-
// we need to leave ( a lot ) of room for other things as well, so we limit the cache size
- var val = (totalPhysicalMemoryMegabytes / 2) -
+ var val = (MemoryStatistics.TotalPhysicalMemory / 2) -
// reduce the unmanaged cache size from the default limit
(GetConfigurationValue<int>("Raven/Esent/CacheSizeMax") ?? 1024);
@@ -268,34 +265,6 @@ private int GetDefaultMemoryCacheLimitMegabytes()
return val;
}
- private static int GetTotalPhysicalMemoryMegabytes()
- {
- int totalPhysicalMemoryMegabytes;
- if (Type.GetType("Mono.Runtime") != null)
- {
- totalPhysicalMemoryMegabytes = GetDefaultMemoryCacheLimitMegabytesOnMono();
- }
- else
- {
-#if __MonoCS__
- throw new PlatformNotSupportedException("This build can only run on Mono");
-#else
- totalPhysicalMemoryMegabytes =
- (int) (new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory/1024/1024);
-#endif
- }
- return totalPhysicalMemoryMegabytes;
- }
-
- private static int GetDefaultMemoryCacheLimitMegabytesOnMono()
- {
- var pc = new System.Diagnostics.PerformanceCounter("Mono Memory", "Total Physical Memory");
- var totalPhysicalMemoryMegabytes = (int)(pc.RawValue / 1024 / 1024);
- if (totalPhysicalMemoryMegabytes == 0)
- totalPhysicalMemoryMegabytes = 128; // 128MB, the Mono runtime default
- return totalPhysicalMemoryMegabytes;
- }
-
public NameValueCollection Settings { get; set; }
public string ServerUrl
@@ -635,37 +604,6 @@ public string IndexStoragePath
}
}
- private bool failedToGetAvailablePhysicalMemory;
- public int AvailablePhysicalMemoryInMegabytes
- {
- get
- {
- if (failedToGetAvailablePhysicalMemory)
- return -1;
-
- try
- {
- var availablePhysicalMemoryInMb = GetTotalPhysicalMemoryMegabytes();
- if(Environment.Is64BitProcess)
- return availablePhysicalMemoryInMb;
-
- // we are in 32 bits mode, but the _system_ may have more than 4 GB available
- // so we have to check the _address space_ as well as the available memory
- var workingSetMb = (int) (Process.GetCurrentProcess().WorkingSet64/1024/1024);
- return Math.Min(2048 - workingSetMb, availablePhysicalMemoryInMb);
- }
- catch (Exception)
- {
- if (Type.GetType("Mono.Runtime") == null)
- throw;
-
- // I don't know how to figur eout free RAM on mono, so we disable this behavior
- failedToGetAvailablePhysicalMemory = true;
- return -1;
- }
- }
- }
-
public int AvailableMemoryForRaisingIndexBatchSizeLimit { get; set; }
protected void ResetContainer()
View
91 Raven.Database/Config/MemoryStatistics.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Text.RegularExpressions;
+
+namespace Raven.Database.Config
+{
+ internal static class MemoryStatistics
+ {
+ private static bool failedToGetAvailablePhysicalMemory;
+ private static bool failedToGetTotalPhysicalMemory;
+
+ public static int TotalPhysicalMemory
+ {
+ get
+ {
+ if (failedToGetTotalPhysicalMemory)
+ return -1;
+
+ if (Type.GetType("Mono.Runtime") != null)
+ {
+ var pc = new PerformanceCounter("Mono Memory", "Total Physical Memory");
+ var totalPhysicalMemoryMegabytes = (int)(pc.RawValue / 1024 / 1024);
+ if (totalPhysicalMemoryMegabytes == 0)
+ totalPhysicalMemoryMegabytes = 128; // 128MB, the Mono runtime default
+ return totalPhysicalMemoryMegabytes;
+ }
+#if __MonoCS__
+ throw new PlatformNotSupportedException("This build can only run on Mono");
+#else
+ try
+ {
+ return (int) (new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory/1024/1024);
+ }
+ catch
+ {
+ failedToGetTotalPhysicalMemory = true;
+ return -1;
+ }
+#endif
+ }
+ }
+
+ public static int AvailablePhysicalMemory
+ {
+ get
+ {
+ if (failedToGetAvailablePhysicalMemory)
+ return -1;
+
+ if (Type.GetType("Mono.Runtime") != null)
+ {
+ // Try /proc/meminfo, which will work on Linux only!
+ if (File.Exists("/proc/meminfo"))
+ {
+ using (TextReader reader = File.OpenText("/proc/meminfo"))
+ {
+ var match = Regex.Match(reader.ReadToEnd(), @"MemFree:\s*(\d+) kB");
+ if (match.Success)
+ {
+ return Convert.ToInt32(match.Groups[1].Value) / 1024;
+ }
+ }
+ }
+ failedToGetAvailablePhysicalMemory = true;
+ return -1;
+ }
+#if __MonoCS__
+ throw new PlatformNotSupportedException("This build can only run on Mono");
+#else
+ try
+ {
+ var availablePhysicalMemoryInMb = (int)(new Microsoft.VisualBasic.Devices.ComputerInfo().AvailablePhysicalMemory / 1024 / 1024);
+ if (Environment.Is64BitProcess)
+ return availablePhysicalMemoryInMb;
+
+ // we are in 32 bits mode, but the _system_ may have more than 4 GB available
+ // so we have to check the _address space_ as well as the available memory
+ var workingSetMb = (int)(Process.GetCurrentProcess().WorkingSet64 / 1024 / 1024);
+ return Math.Min(2048 - workingSetMb, availablePhysicalMemoryInMb);
+ }
+ catch
+ {
+ failedToGetAvailablePhysicalMemory = true;
+ return -1;
+ }
+#endif
+ }
+ }
+ }
+}
View
12 Raven.Database/Indexing/IndexBatchSizeAutoTuner.cs
@@ -1,4 +1,5 @@
using System;
+using Raven.Database.Config;
namespace Raven.Database.Indexing
{
@@ -69,8 +70,7 @@ private void ConsiderIncreasingBatchSize(int amountOfItemsToIndex, int size)
// not all 10
var sizedPlusIndexingCost = sizeInMegabytes * (1 + (0.25 * Math.Min(context.IndexDefinitionStorage.IndexesCount, context.Configuration.MaxNumberOfParallelIndexTasks)));
- var availablePhysicalMemoryInMegabytes = context.Configuration.AvailablePhysicalMemoryInMegabytes;
- var remainingMemoryAfterBatchSizeIncrease = availablePhysicalMemoryInMegabytes - sizedPlusIndexingCost;
+ var remainingMemoryAfterBatchSizeIncrease = MemoryStatistics.AvailablePhysicalMemory - sizedPlusIndexingCost;
if (remainingMemoryAfterBatchSizeIncrease >= context.Configuration.AvailableMemoryForRaisingIndexBatchSizeLimit)
{
@@ -84,8 +84,7 @@ private void ConsiderIncreasingBatchSize(int amountOfItemsToIndex, int size)
private bool ReduceBatchSizeIfCloseToMemoryCeiling()
{
- if (context.Configuration.AvailablePhysicalMemoryInMegabytes >=
- context.Configuration.AvailableMemoryForRaisingIndexBatchSizeLimit)
+ if (MemoryStatistics.AvailablePhysicalMemory >= context.Configuration.AvailableMemoryForRaisingIndexBatchSizeLimit)
{
// there is enough memory available for the next indexing run
return false;
@@ -103,8 +102,7 @@ private bool ReduceBatchSizeIfCloseToMemoryCeiling()
// let us check again after the GC call, do we still need to reduce the batch size?
- if (context.Configuration.AvailablePhysicalMemoryInMegabytes >
- context.Configuration.AvailableMemoryForRaisingIndexBatchSizeLimit)
+ if (MemoryStatistics.AvailablePhysicalMemory > context.Configuration.AvailableMemoryForRaisingIndexBatchSizeLimit)
{
// we don't want to try increasing things, we just hit the ceiling, maybe on the next try
return true;
@@ -113,7 +111,7 @@ private bool ReduceBatchSizeIfCloseToMemoryCeiling()
// we are still too high, let us reduce the size and see what is going on.
NumberOfItemsToIndexInSingleBatch = Math.Max(context.Configuration.InitialNumberOfItemsToIndexInSingleBatch,
- NumberOfItemsToIndexInSingleBatch / 2);
+ NumberOfItemsToIndexInSingleBatch / 2);
return true;
}
View
1 Raven.Database/Raven.Database.csproj
@@ -115,6 +115,7 @@
<Compile Include="Commercial\ValidateLicense.cs" />
<Compile Include="Config\CertGenerator.cs" />
<Compile Include="Config\ConfigOptionDocs.cs" />
+ <Compile Include="Config\MemoryStatistics.cs" />
<Compile Include="Impl\ExceptionAggregator.cs" />
<Compile Include="Indexing\DefaultBackgroundTaskExecuter.cs" />
<Compile Include="Indexing\IBackgroundTaskExecuter.cs" />

0 comments on commit f3b8ca3

Please sign in to comment.
Something went wrong with that request. Please try again.