1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System
.Runtime
.CompilerServices
;
9 public enum GCCollectionMode
16 public enum GCNotificationStatus
25 public static partial class GC
27 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
28 extern static int GetCollectionCount (int generation
);
30 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
31 extern static int GetMaxGeneration ();
33 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
34 extern static void InternalCollect (int generation
);
36 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
37 extern static void RecordPressure (long bytesAllocated
);
39 // TODO: Move following to ConditionalWeakTable
40 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
41 internal extern static void register_ephemeron_array (Ephemeron
[] array
);
43 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
44 extern static object get_ephemeron_tombstone ();
46 internal static readonly object EPHEMERON_TOMBSTONE
= get_ephemeron_tombstone ();
48 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
49 public static extern long GetAllocatedBytesForCurrentThread ();
51 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
52 public static extern long GetTotalAllocatedBytes (bool precise
= false);
54 public static void AddMemoryPressure (long bytesAllocated
)
56 if (bytesAllocated
<= 0)
57 throw new ArgumentOutOfRangeException (nameof (bytesAllocated
), SR
.ArgumentOutOfRange_NeedPosNum
);
58 if (IntPtr
.Size
== 4 && bytesAllocated
> Int32
.MaxValue
)
59 throw new ArgumentOutOfRangeException (nameof (bytesAllocated
), SR
.ArgumentOutOfRange_MustBeNonNegInt32
);
60 RecordPressure (bytesAllocated
);
63 public static void RemoveMemoryPressure (long bytesAllocated
)
65 if (bytesAllocated
<= 0)
66 throw new ArgumentOutOfRangeException (nameof (bytesAllocated
), SR
.ArgumentOutOfRange_NeedPosNum
);
67 if (IntPtr
.Size
== 4 && bytesAllocated
> Int32
.MaxValue
)
68 throw new ArgumentOutOfRangeException (nameof (bytesAllocated
), SR
.ArgumentOutOfRange_MustBeNonNegInt32
);
69 RecordPressure (-bytesAllocated
);
72 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
73 public static extern int GetGeneration (object obj
);
75 public static void Collect (int generation
)
77 Collect (generation
, GCCollectionMode
.Default
);
80 public static void Collect ()
82 InternalCollect (MaxGeneration
);
85 public static void Collect (int generation
, GCCollectionMode mode
) => Collect (generation
, mode
, true);
87 public static void Collect (int generation
, GCCollectionMode mode
, bool blocking
) => Collect (generation
, mode
, blocking
, false);
89 public static void Collect (int generation
, GCCollectionMode mode
, bool blocking
, bool compacting
)
92 throw new ArgumentOutOfRangeException (nameof (generation
), "generation", SR
.ArgumentOutOfRange_GenericPositive
);
93 if ((mode
< GCCollectionMode
.Default
) || (mode
> GCCollectionMode
.Optimized
))
94 throw new ArgumentOutOfRangeException (nameof (mode
), SR
.ArgumentOutOfRange_Enum
);
96 InternalCollect (generation
);
99 public static int CollectionCount (int generation
)
102 throw new ArgumentOutOfRangeException (nameof (generation
), SR
.ArgumentOutOfRange_GenericPositive
);
103 return GetCollectionCount (generation
);
106 [MethodImplAttribute (MethodImplOptions
.NoInlining
)] // disable optimizations
107 public static void KeepAlive (object obj
)
111 public static int GetGeneration (WeakReference wo
)
113 object obj
= wo
.Target
;
115 throw new ArgumentException ();
116 return GetGeneration (obj
);
119 public static int MaxGeneration
{
121 return GetMaxGeneration ();
125 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
126 public static extern void WaitForPendingFinalizers ();
128 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
129 static extern void _SuppressFinalize (object o
);
131 public static void SuppressFinalize (object obj
)
134 throw new ArgumentNullException (nameof (obj
));
135 _SuppressFinalize (obj
);
138 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
139 static extern void _ReRegisterForFinalize (object o
);
141 public static void ReRegisterForFinalize (object obj
)
144 throw new ArgumentNullException (nameof (obj
));
145 _ReRegisterForFinalize (obj
);
148 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
149 public extern static long GetTotalMemory (bool forceFullCollection
);
151 static bool _RegisterForFullGCNotification (int maxGenerationPercentage
, int largeObjectHeapPercentage
)
153 throw new NotImplementedException ();
156 static bool _CancelFullGCNotification ()
158 throw new NotImplementedException ();
161 static GCNotificationStatus
_WaitForFullGCApproach (int millisecondsTimeout
)
163 throw new NotImplementedException ();
166 static GCNotificationStatus
_WaitForFullGCComplete (int millisecondsTimeout
)
168 throw new NotImplementedException ();
171 public static void RegisterForFullGCNotification (int maxGenerationThreshold
, int largeObjectHeapThreshold
)
173 if ((maxGenerationThreshold
<= 0) || (maxGenerationThreshold
>= 100))
174 throw new ArgumentOutOfRangeException (nameof (maxGenerationThreshold
),
175 SR
.Format (SR
.ArgumentOutOfRange_Bounds_Lower_Upper
, 1, 99));
176 if ((largeObjectHeapThreshold
<= 0) || (largeObjectHeapThreshold
>= 100))
177 throw new ArgumentOutOfRangeException (nameof (largeObjectHeapThreshold
),
178 SR
.Format (SR
.ArgumentOutOfRange_Bounds_Lower_Upper
, 1, 99));
180 if (!_RegisterForFullGCNotification (maxGenerationThreshold
, largeObjectHeapThreshold
))
181 throw new InvalidOperationException (SR
.InvalidOperation_NotWithConcurrentGC
);
184 public static void CancelFullGCNotification ()
186 if (!_CancelFullGCNotification ())
187 throw new InvalidOperationException (SR
.InvalidOperation_NotWithConcurrentGC
);
190 public static GCNotificationStatus
WaitForFullGCApproach ()
192 return (GCNotificationStatus
) _WaitForFullGCApproach (-1);
195 public static GCNotificationStatus
WaitForFullGCApproach (int millisecondsTimeout
)
197 if (millisecondsTimeout
< -1)
198 throw new ArgumentOutOfRangeException (nameof (millisecondsTimeout
), SR
.ArgumentOutOfRange_NeedNonNegOrNegative1
);
200 return _WaitForFullGCApproach (millisecondsTimeout
);
203 public static GCNotificationStatus
WaitForFullGCComplete ()
205 return _WaitForFullGCComplete (-1);
208 public static GCNotificationStatus
WaitForFullGCComplete (int millisecondsTimeout
)
210 if (millisecondsTimeout
< -1)
211 throw new ArgumentOutOfRangeException (nameof (millisecondsTimeout
), SR
.ArgumentOutOfRange_NeedNonNegOrNegative1
);
212 return _WaitForFullGCComplete (millisecondsTimeout
);
215 static bool StartNoGCRegion (long totalSize
, bool hasLohSize
, long lohSize
, bool disallowFullBlockingGC
)
217 throw new NotImplementedException ();
220 public static bool TryStartNoGCRegion (long totalSize
) => StartNoGCRegion (totalSize
, false, 0, false);
222 public static bool TryStartNoGCRegion (long totalSize
, long lohSize
) => StartNoGCRegion (totalSize
, true, lohSize
, false);
224 public static bool TryStartNoGCRegion (long totalSize
, bool disallowFullBlockingGC
) => StartNoGCRegion (totalSize
, false, 0, disallowFullBlockingGC
);
226 public static bool TryStartNoGCRegion (long totalSize
, long lohSize
, bool disallowFullBlockingGC
) => StartNoGCRegion (totalSize
, true, lohSize
, disallowFullBlockingGC
);
228 public static void EndNoGCRegion ()
230 throw new NotImplementedException ();
233 internal static ulong GetSegmentSize ()
236 return 1024 * 1024 * 16;
239 public static GCMemoryInfo
GetGCMemoryInfo ()
245 internal static T
[] AllocateUninitializedArray
<T
> (int length
)
247 // Mono only does explicit zeroning if the array is to big for the nursery, but less than 1 Mb - 4 kb.
248 // If it is bigger than that, we grab memoroy directly from the OS which comes pre-zeroed.
249 // Experimentation shows that if we just skip the zeroing in this case, we do not save a measurable
250 // amount of time. So we just allocate the normal way here.
251 // Revist if we change LOS implementation.
252 return new T
[length
];