Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5cb0af2

Browse files
authored
System.GC F# snippets (#7624)
* GC F# snippets * related type snippet refs
1 parent 9a6f72e commit 5cb0af2

File tree

24 files changed

+715
-0
lines changed

24 files changed

+715
-0
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// <Snippet1>
2+
// <Snippet2>
3+
open System
4+
open System.Threading
5+
6+
// Variable for continual checking in the
7+
// While loop in the WaitForFullGCProc method.
8+
let mutable checkForNotify = false
9+
10+
// Variable for suspending work
11+
// (such servicing allocated server requests)
12+
// after a notification is received and then
13+
// resuming allocation after inducing a garbage collection.
14+
let mutable bAllocate = false
15+
16+
// Variable for ending the example.
17+
let mutable finalExit = false
18+
19+
// Collection for objects that simulate the server request workload.
20+
let load = ResizeArray<byte []>()
21+
22+
23+
// <Snippet9>
24+
let redirectRequests () =
25+
// Code that sends requests
26+
// to other servers.
27+
28+
// Suspend work.
29+
bAllocate <- false
30+
31+
let finishExistingRequests () =
32+
// Code that waits a period of time
33+
// for pending requests to finish.
34+
35+
// Clear the simulated workload.
36+
load.Clear()
37+
38+
let acceptRequests () =
39+
// Code that resumes processing
40+
// requests on this server.
41+
42+
// Resume work.
43+
bAllocate <- true
44+
// </Snippet9>
45+
46+
// <Snippet5>
47+
let onFullGCApproachNotify () =
48+
printfn "Redirecting requests."
49+
50+
// Method that tells the request queuing
51+
// server to not direct requests to this server.
52+
redirectRequests ()
53+
54+
// Method that provides time to
55+
// finish processing pending requests.
56+
finishExistingRequests ()
57+
58+
// This is a good time to induce a GC collection
59+
// because the runtime will induce a full GC soon.
60+
// To be very careful, you can check precede with a
61+
// check of the GC.GCCollectionCount to make sure
62+
// a full GC did not already occur since last notified.
63+
GC.Collect()
64+
printfn "Induced a collection."
65+
// </Snippet5>
66+
67+
68+
// <Snippet6>
69+
let onFullGCCompleteEndNotify () =
70+
// Method that informs the request queuing server
71+
// that this server is ready to accept requests again.
72+
acceptRequests ()
73+
printfn "Accepting requests again."
74+
// </Snippet6>
75+
76+
// <Snippet8>
77+
let waitForFullGCProc () =
78+
let mutable broken = false
79+
80+
while not broken do
81+
let mutable broken = false
82+
// CheckForNotify is set to true and false in Main.
83+
while checkForNotify && not broken do
84+
// <Snippet3>
85+
// Check for a notification of an approaching collection.
86+
match GC.WaitForFullGCApproach() with
87+
| GCNotificationStatus.Succeeded ->
88+
printfn "GC Notification raised."
89+
onFullGCApproachNotify ()
90+
// <Snippet4>
91+
// Check for a notification of a completed collection.
92+
match GC.WaitForFullGCComplete() with
93+
| GCNotificationStatus.Succeeded ->
94+
printfn "GC Notification raised."
95+
onFullGCCompleteEndNotify ()
96+
| GCNotificationStatus.Canceled ->
97+
printfn "GC Notification cancelled."
98+
broken <- true
99+
| _ ->
100+
// Could be a time out.
101+
printfn "GC Notification not applicable."
102+
broken <- true
103+
// </Snippet4>
104+
| GCNotificationStatus.Canceled ->
105+
printfn "GC Notification cancelled."
106+
broken <- true
107+
| _ ->
108+
// This can occur if a timeout period
109+
// is specified for WaitForFullGCApproach(Timeout)
110+
// or WaitForFullGCComplete(Timeout)
111+
// and the time out period has elapsed.
112+
printfn "GC Notification not applicable."
113+
broken <- true
114+
// </Snippet3>
115+
116+
Thread.Sleep 500
117+
// FinalExit is set to true right before
118+
// the main thread cancelled notification.
119+
if finalExit then broken <- true
120+
// </Snippet8>
121+
122+
123+
124+
try
125+
// Register for a notification.
126+
GC.RegisterForFullGCNotification(10, 10)
127+
printfn "Registered for GC notification."
128+
129+
checkForNotify <- true
130+
bAllocate <- true
131+
132+
// Start a thread using WaitForFullGCProc.
133+
let thWaitForFullGC = Thread(ThreadStart waitForFullGCProc)
134+
thWaitForFullGC.Start()
135+
136+
// While the thread is checking for notifications in
137+
// WaitForFullGCProc, create objects to simulate a server workload.
138+
try
139+
let mutable lastCollCount = 0
140+
let mutable newCollCount = 0
141+
142+
let mutable broken = false
143+
144+
while not broken do
145+
if bAllocate then
146+
load.Add(Array.zeroCreate<byte> 1000)
147+
newCollCount <- GC.CollectionCount 2
148+
149+
if newCollCount <> lastCollCount then
150+
// Show collection count when it increases:
151+
printfn $"Gen 2 collection count: {GC.CollectionCount(2)}"
152+
lastCollCount <- newCollCount
153+
// For ending the example (arbitrary).
154+
if newCollCount = 500 then
155+
finalExit <- true
156+
checkForNotify <- false
157+
broken <- true
158+
with :? OutOfMemoryException -> printfn "Out of memory."
159+
160+
// <Snippet7>
161+
finalExit <- true
162+
checkForNotify <- false
163+
GC.CancelFullGCNotification()
164+
// </Snippet7>
165+
with :? InvalidOperationException as invalidOp ->
166+
printfn $"GC Notifications are not supported while concurrent GC is enabled.\n{invalidOp.Message}"
167+
// </Snippet2>
168+
// </Snippet1>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="Program.fs" />
8+
</ItemGroup>
9+
</Project>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Program
2+
3+
//<Snippet1>
4+
open System
5+
6+
GC.Collect(2, GCCollectionMode.Optimized)
7+
// </Snippet1>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module class1
2+
3+
// <Snippet1>
4+
open System
5+
6+
let maxGarbage = 1000
7+
8+
let makeSomeGarbage () =
9+
// Create objects and release them to fill up memory with unused objects.
10+
for _ = 1 to maxGarbage do
11+
Version() |> ignore
12+
13+
// Put some objects in memory.
14+
makeSomeGarbage()
15+
printfn $"Memory used before collection: {GC.GetTotalMemory false:N0}"
16+
17+
// Collect all generations of memory.
18+
GC.Collect()
19+
printfn $"Memory used after full collection: {GC.GetTotalMemory true:N0}"
20+
21+
// The output from the example resembles the following:
22+
// Memory used before collection: 79,392
23+
// Memory used after full collection: 52,640
24+
// </Snippet1>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module collect4
2+
3+
open System
4+
open System.Runtime
5+
6+
let createObjects () =
7+
Array.init 10000 (fun i ->
8+
let s1= "word1"
9+
let s2 = "word2"
10+
s1 + " " + s2 )
11+
|> ignore
12+
13+
createObjects ()
14+
printfn $"Memory allocated before GC: {GC.GetTotalMemory false:N0}"
15+
// <Snippet1>
16+
GCSettings.LargeObjectHeapCompactionMode <- GCLargeObjectHeapCompactionMode.CompactOnce
17+
GC.Collect(2, GCCollectionMode.Forced, true, true)
18+
// </Snippet1>
19+
printfn $"Memory allocated after GC: {GC.GetTotalMemory false:N0}"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="lohcompactionmode1.fs" />
8+
<Compile Include="class1.fs" />
9+
<Compile Include="Program.fs" />
10+
<Compile Include="collect4.fs" />
11+
</ItemGroup>
12+
</Project>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module lohcompactionmode1
2+
3+
open System
4+
open System.Runtime
5+
6+
// <Snippet1>
7+
GCSettings.LargeObjectHeapCompactionMode <- GCLargeObjectHeapCompactionMode.CompactOnce
8+
GC.Collect()
9+
// </Snippet1>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
open System
2+
open System.Runtime
3+
4+
// <Snippet1>
5+
if GCSettings.LatencyMode = GCLatencyMode.NoGCRegion then
6+
GC.EndNoGCRegion()
7+
// </Snippet1>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="endnogcregion1.fs" />
8+
</ItemGroup>
9+
</Project>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="systemgcgetgenerationweak.fs" />
8+
</ItemGroup>
9+
</Project>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//<snippet1>
2+
open System
3+
4+
let maxGarbage = 1000
5+
6+
[<AllowNullLiteral>]
7+
type MyGCCollectClass() =
8+
member _.MakeSomeGarbage() =
9+
for i = 1 to maxGarbage do
10+
// Create objects and release them to fill up memory
11+
// with unused objects.
12+
Version() |> ignore
13+
14+
// Create a strong reference to an object.
15+
let mutable myGCCol = MyGCCollectClass()
16+
17+
// Put some objects in memory.
18+
myGCCol.MakeSomeGarbage()
19+
20+
// Get the generation of managed memory where myGCCol is stored.
21+
printfn $"The object is in generation: {GC.GetGeneration myGCCol}"
22+
23+
// Perform a full garbage collection.
24+
// Because there is a strong reference to myGCCol, it will
25+
// not be garbage collected.
26+
GC.Collect()
27+
28+
// Get the generation of managed memory where myGCCol is stored.
29+
printfn $"The object is in generation: {GC.GetGeneration myGCCol}"
30+
31+
// Create a WeakReference to myGCCol.
32+
let wkref = WeakReference myGCCol
33+
// Remove the strong reference to myGCCol.
34+
myGCCol <- null
35+
36+
// Get the generation of managed memory where wkref is stored.
37+
printfn $"The WeakReference to the object is in generation: {GC.GetGeneration wkref}"
38+
39+
// Perform another full garbage collection.
40+
// A WeakReference will not survive a garbage collection.
41+
GC.Collect()
42+
43+
// Try to get the generation of managed memory where wkref is stored.
44+
// Because it has been collected, an exception will be thrown.
45+
try
46+
printfn $"The WeakReference to the object is in generation: {GC.GetGeneration wkref}"
47+
stdin.Read() |> ignore
48+
with e ->
49+
printfn $"The WeakReference to the object has been garbage collected: '{e}'"
50+
stdin.Read() |> ignore
51+
52+
//</snippet1>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="gckeepalive.fs" />
8+
</ItemGroup>
9+
</Project>

0 commit comments

Comments
 (0)