[Mono-dev] Large object size limits
Neale Ferguson
NealeFerguson at verizon.net
Thu Jun 12 20:38:26 UTC 2014
The following program runs fine on .NET -
using System;
using System.Collections.Generic;
using System.Runtime;
using System.Text;
namespace LargeObjectTest
{
class Program
{
static void Main(string[] args)
{
IList<double> myList = new List<double>();
long index = 1024*1024*1024;
Console.WriteLine("index:" + index);
double[] array = null;
Console.WriteLine("UInt32.MaxValue: "+UInt32.MaxValue);
try
{
array = new double[index];
Console.WriteLine("doubleArray:LongLength " + array.Length * sizeof(double) + " bytes");
Console.WriteLine("sizeof(double) " + sizeof(double) + " bytes");
Console.WriteLine("index " + index);
Console.WriteLine("doubleArray:LongLength " + array.LongLength);
Console.WriteLine("doubleArray:Size " + array.LongLength * sizeof(double) * 1.0 + " Bytes");
}
catch (Exception e)
{
Console.WriteLine("Exception:" + e);
Console.WriteLine("Exception:" + e.Message + " allocating :" + index);
Console.WriteLine("Exception:" + e.Message + " allocating :" + index * sizeof(double));
}
}
}
}
However, on mono on Linux it results in:
index:1073741824
UInt32.MaxValue: 4294967295
Exception:System.OutOfMemoryException: Out of memory
at (wrapper managed-to-native) object:__icall_wrapper_mono_array_new_specific (intptr,int)
at LargeObjectTest.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
Exception:Out of memory allocating :1073741824
Exception:Out of memory allocating :8589934592
If I make the following change to override the SIZE_MAX value from /usr/include/stdint.h:
--- a/mono/metadata/sgen-los.c
+++ b/mono/metadata/sgen-los.c
@@ -342,8 +342,12 @@ sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size)
*
* size <= SIZE_MAX - (mono_pagesize () - 1) - sizeof (LOSObject)
*/
+#undef SIZE_MAX
+#define SIZE_MAX (17179869184U)
if (size > SIZE_MAX - (mono_pagesize () - 1) - sizeof (LOSObject))
return NULL;
+#undef SIZE_MAX
+#define SIZE_MAX (4294967295U)
#ifdef LOS_DUMMY
if (!los_segment)
Then the program works as it does under .NET:
index:1073741824
UInt32.MaxValue: 4294967295
doubleArray:LongLength 0 bytes
sizeof(double) 8 bytes
index 1073741824
doubleArray:LongLength 1073741824
doubleArray:Size 8589934592 Bytes
The question is, what is the correct value for the comparison in lieu of SIZE_MAX? I can't determine what the max is on .NET. Another question is what type of compacting happens with large objects like this?
Neale
More information about the Mono-devel-list
mailing list