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

Skip to content

System.GC F# snippets #7624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// <Snippet1>
// <Snippet2>
open System
open System.Threading

// Variable for continual checking in the
// While loop in the WaitForFullGCProc method.
let mutable checkForNotify = false

// Variable for suspending work
// (such servicing allocated server requests)
// after a notification is received and then
// resuming allocation after inducing a garbage collection.
let mutable bAllocate = false

// Variable for ending the example.
let mutable finalExit = false

// Collection for objects that simulate the server request workload.
let load = ResizeArray<byte []>()


// <Snippet9>
let redirectRequests () =
// Code that sends requests
// to other servers.

// Suspend work.
bAllocate <- false

let finishExistingRequests () =
// Code that waits a period of time
// for pending requests to finish.

// Clear the simulated workload.
load.Clear()

let acceptRequests () =
// Code that resumes processing
// requests on this server.

// Resume work.
bAllocate <- true
// </Snippet9>

// <Snippet5>
let onFullGCApproachNotify () =
printfn "Redirecting requests."

// Method that tells the request queuing
// server to not direct requests to this server.
redirectRequests ()

// Method that provides time to
// finish processing pending requests.
finishExistingRequests ()

// This is a good time to induce a GC collection
// because the runtime will induce a full GC soon.
// To be very careful, you can check precede with a
// check of the GC.GCCollectionCount to make sure
// a full GC did not already occur since last notified.
GC.Collect()
printfn "Induced a collection."
// </Snippet5>


// <Snippet6>
let onFullGCCompleteEndNotify () =
// Method that informs the request queuing server
// that this server is ready to accept requests again.
acceptRequests ()
printfn "Accepting requests again."
// </Snippet6>

// <Snippet8>
let waitForFullGCProc () =
let mutable broken = false

while not broken do
let mutable broken = false
// CheckForNotify is set to true and false in Main.
while checkForNotify && not broken do
// <Snippet3>
// Check for a notification of an approaching collection.
match GC.WaitForFullGCApproach() with
| GCNotificationStatus.Succeeded ->
printfn "GC Notification raised."
onFullGCApproachNotify ()
// <Snippet4>
// Check for a notification of a completed collection.
match GC.WaitForFullGCComplete() with
| GCNotificationStatus.Succeeded ->
printfn "GC Notification raised."
onFullGCCompleteEndNotify ()
| GCNotificationStatus.Canceled ->
printfn "GC Notification cancelled."
broken <- true
| _ ->
// Could be a time out.
printfn "GC Notification not applicable."
broken <- true
// </Snippet4>
| GCNotificationStatus.Canceled ->
printfn "GC Notification cancelled."
broken <- true
| _ ->
// This can occur if a timeout period
// is specified for WaitForFullGCApproach(Timeout)
// or WaitForFullGCComplete(Timeout)
// and the time out period has elapsed.
printfn "GC Notification not applicable."
broken <- true
// </Snippet3>

Thread.Sleep 500
// FinalExit is set to true right before
// the main thread cancelled notification.
if finalExit then broken <- true
// </Snippet8>



try
// Register for a notification.
GC.RegisterForFullGCNotification(10, 10)
printfn "Registered for GC notification."

checkForNotify <- true
bAllocate <- true

// Start a thread using WaitForFullGCProc.
let thWaitForFullGC = Thread(ThreadStart waitForFullGCProc)
thWaitForFullGC.Start()

// While the thread is checking for notifications in
// WaitForFullGCProc, create objects to simulate a server workload.
try
let mutable lastCollCount = 0
let mutable newCollCount = 0

let mutable broken = false

while not broken do
if bAllocate then
load.Add(Array.zeroCreate<byte> 1000)
newCollCount <- GC.CollectionCount 2

if newCollCount <> lastCollCount then
// Show collection count when it increases:
printfn $"Gen 2 collection count: {GC.CollectionCount(2)}"
lastCollCount <- newCollCount
// For ending the example (arbitrary).
if newCollCount = 500 then
finalExit <- true
checkForNotify <- false
broken <- true
with :? OutOfMemoryException -> printfn "Out of memory."

// <Snippet7>
finalExit <- true
checkForNotify <- false
GC.CancelFullGCNotification()
// </Snippet7>
with :? InvalidOperationException as invalidOp ->
printfn $"GC Notifications are not supported while concurrent GC is enabled.\n{invalidOp.Message}"
// </Snippet2>
// </Snippet1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
</Project>
7 changes: 7 additions & 0 deletions samples/snippets/fsharp/System/GC/Collect/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Program

//<Snippet1>
open System

GC.Collect(2, GCCollectionMode.Optimized)
// </Snippet1>
24 changes: 24 additions & 0 deletions samples/snippets/fsharp/System/GC/Collect/class1.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module class1

// <Snippet1>
open System

let maxGarbage = 1000

let makeSomeGarbage () =
// Create objects and release them to fill up memory with unused objects.
for _ = 1 to maxGarbage do
Version() |> ignore

// Put some objects in memory.
makeSomeGarbage()
printfn $"Memory used before collection: {GC.GetTotalMemory false:N0}"

// Collect all generations of memory.
GC.Collect()
printfn $"Memory used after full collection: {GC.GetTotalMemory true:N0}"

// The output from the example resembles the following:
// Memory used before collection: 79,392
// Memory used after full collection: 52,640
// </Snippet1>
19 changes: 19 additions & 0 deletions samples/snippets/fsharp/System/GC/Collect/collect4.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module collect4

open System
open System.Runtime

let createObjects () =
Array.init 10000 (fun i ->
let s1= "word1"
let s2 = "word2"
s1 + " " + s2 )
|> ignore

createObjects ()
printfn $"Memory allocated before GC: {GC.GetTotalMemory false:N0}"
// <Snippet1>
GCSettings.LargeObjectHeapCompactionMode <- GCLargeObjectHeapCompactionMode.CompactOnce
GC.Collect(2, GCCollectionMode.Forced, true, true)
// </Snippet1>
printfn $"Memory allocated after GC: {GC.GetTotalMemory false:N0}"
12 changes: 12 additions & 0 deletions samples/snippets/fsharp/System/GC/Collect/fs.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="lohcompactionmode1.fs" />
<Compile Include="class1.fs" />
<Compile Include="Program.fs" />
<Compile Include="collect4.fs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module lohcompactionmode1

open System
open System.Runtime

// <Snippet1>
GCSettings.LargeObjectHeapCompactionMode <- GCLargeObjectHeapCompactionMode.CompactOnce
GC.Collect()
// </Snippet1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
open System
open System.Runtime

// <Snippet1>
if GCSettings.LatencyMode = GCLatencyMode.NoGCRegion then
GC.EndNoGCRegion()
// </Snippet1>
9 changes: 9 additions & 0 deletions samples/snippets/fsharp/System/GC/EndNoGCRegion/fs.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="endnogcregion1.fs" />
</ItemGroup>
</Project>
9 changes: 9 additions & 0 deletions samples/snippets/fsharp/System/GC/GetGeneration/fs.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="systemgcgetgenerationweak.fs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//<snippet1>
open System

let maxGarbage = 1000

[<AllowNullLiteral>]
type MyGCCollectClass() =
member _.MakeSomeGarbage() =
for i = 1 to maxGarbage do
// Create objects and release them to fill up memory
// with unused objects.
Version() |> ignore

// Create a strong reference to an object.
let mutable myGCCol = MyGCCollectClass()

// Put some objects in memory.
myGCCol.MakeSomeGarbage()

// Get the generation of managed memory where myGCCol is stored.
printfn $"The object is in generation: {GC.GetGeneration myGCCol}"

// Perform a full garbage collection.
// Because there is a strong reference to myGCCol, it will
// not be garbage collected.
GC.Collect()

// Get the generation of managed memory where myGCCol is stored.
printfn $"The object is in generation: {GC.GetGeneration myGCCol}"

// Create a WeakReference to myGCCol.
let wkref = WeakReference myGCCol
// Remove the strong reference to myGCCol.
myGCCol <- null

// Get the generation of managed memory where wkref is stored.
printfn $"The WeakReference to the object is in generation: {GC.GetGeneration wkref}"

// Perform another full garbage collection.
// A WeakReference will not survive a garbage collection.
GC.Collect()

// Try to get the generation of managed memory where wkref is stored.
// Because it has been collected, an exception will be thrown.
try
printfn $"The WeakReference to the object is in generation: {GC.GetGeneration wkref}"
stdin.Read() |> ignore
with e ->
printfn $"The WeakReference to the object has been garbage collected: '{e}'"
stdin.Read() |> ignore

//</snippet1>
9 changes: 9 additions & 0 deletions samples/snippets/fsharp/System/GC/KeepAlive/fs.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="gckeepalive.fs" />
</ItemGroup>
</Project>
Loading