Skip to content

Commit db2c0ea

Browse files
authored
Adds more garbage collection settings (ionide#1896)
* Adds more garbage collection settings * Adds back use of deprecated conserveMemory setting
1 parent 13038fd commit db2c0ea

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

release/package.json

+22-2
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,8 @@
532532
"FSharp.fsac.conserveMemory": {
533533
"default": false,
534534
"description": "Configures FsAutoComplete with settings intended to reduce memory consumption. Requires restart.",
535-
"type": "boolean"
535+
"type": "boolean",
536+
"deprecationMessage": "This setting is deprecated. Use FSharp.fsac.gc.conserveMemory instead."
536537
},
537538
"FSharp.fsac.dotnetArgs": {
538539
"default": [],
@@ -542,6 +543,25 @@
542543
},
543544
"type": "array"
544545
},
546+
"FSharp.fsac.gc.conserveMemory" : {
547+
"markdownDescription": "Configures the garbage collector to [conserve memory](https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#conserve-memory) at the expense of more frequent garbage collections and possibly longer pause times. Acceptable values are 0-9. Any non-zero value will allow the [Large Object Heap](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/large-object-heap) to be compacted automatically if it has too much fragmentation. Requires restart.",
548+
"type": "integer",
549+
"minimum": 0,
550+
"maximum": 9
551+
},
552+
"FSharp.fsac.gc.heapCount" : {
553+
"default": 2,
554+
"markdownDescription": "Limits the number of [heaps](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#the-managed-heap) created by the garbage collector. Applies to server garbage collection only. See [Middle Ground between Server and Workstation GC](https://devblogs.microsoft.com/dotnet/middle-ground-between-server-and-workstation-gc/) for more details. This can allow FSAC to still benefit from Server garbage collection while still limiting the number of heaps. Requires restart.",
555+
"type": "integer",
556+
"required": [
557+
"FSharp.fsac.gc.server"
558+
]
559+
},
560+
"FSharp.fsac.gc.server": {
561+
"default": true,
562+
"markdownDescription": "Configures whether the application uses workstation garbage collection or server garbage collection. See [Workstation vs Server Garbage Collection](https://devblogs.microsoft.com/premier-developer/understanding-different-gc-modes-with-concurrency-visualizer/#workstation-gc-vs-server-gc) for more details. Workstation will use less memory but Server will have more throughput. Requires restart.",
563+
"type": "boolean"
564+
},
545565
"FSharp.fsac.netCoreDllPath": {
546566
"default": "",
547567
"description": "The path to the \u0027fsautocomplete.dll\u0027, a directory containing TFM-specific versions of fsautocomplete.dll, or a directory containing fsautocomplete.dll. Useful for debugging a self-built FSAC. If a DLL is specified, uses it directly. If a directory is specified and it contains TFM-specific folders (net6.0, net7.0, etc) then that directory will be probed for the best TFM to use for the current runtime. This is useful when working with a local copy of FSAC, you can point directly to the bin/Debug or bin/Release folder and it\u0027ll Just Work. Finally, if a directory is specified and there are no TFM paths, then fsautocomplete.dll from that directory is used. Requires restart.",
@@ -1720,4 +1740,4 @@
17201740
"url": "https://github.com/ionide/ionide-vscode-fsharp.git"
17211741
},
17221742
"version": "7.8.2"
1723-
}
1743+
}

src/Core/LanguageService.fs

+33-3
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,36 @@ Consider:
632632
let enableProjectGraph =
633633
"FSharp.enableMSBuildProjectGraph" |> Configuration.get false
634634

635-
let conserveMemory = "FSharp.fsac.conserveMemory" |> Configuration.get false
635+
let tryBool x =
636+
// Boolean.TryParse generates: TypeError: e.match is not a function if we don't call toString first
637+
match Boolean.TryParse(x.ToString()) with
638+
| (true, v) -> Some v
639+
| _ -> None
640+
641+
let tryInt x =
642+
match Int32.TryParse(x.ToString()) with
643+
| (true, v) -> Some v
644+
| _ -> None
645+
646+
let oldgcConserveMemory =
647+
"FSharp.fsac.conserveMemory"
648+
|> Configuration.tryGet
649+
|> Option.map string
650+
|> Option.bind tryBool
651+
652+
let gcConserveMemory =
653+
"FSharp.fsac.gc.conserveMemory" |> Configuration.tryGet |> Option.bind tryInt
654+
655+
let gcConserveMemory =
656+
// prefer new setting, fallback to old, default is 0
657+
match gcConserveMemory, oldgcConserveMemory with
658+
| Some x, _ -> x
659+
| None, Some true -> 9
660+
| None, _ -> 0
661+
662+
let gcHeapCount = "FSharp.fsac.gc.heapCount" |> Configuration.get 2
663+
664+
let gcServer = "FSharp.fsac.gc.server" |> Configuration.get true
636665

637666
let parallelReferenceResolution =
638667
"FSharp.fsac.parallelReferenceResolution" |> Configuration.get false
@@ -788,8 +817,9 @@ Consider:
788817

789818
let fsacEnvVars =
790819
[ yield! fsacEnvVars
791-
if conserveMemory then
792-
yield "DOTNET_GCConserveMemory", box "9"
820+
yield "DOTNET_GCHeapCount", box (gcHeapCount.ToString("X")) // Requires hexadecimal value
821+
yield "DOTNET_GCConserveMemory", box gcConserveMemory
822+
yield "DOTNET_GCServer", box gcServer
793823
if parallelReferenceResolution then
794824
yield "FCS_ParallelReferenceResolution", box "true" ]
795825

0 commit comments

Comments
 (0)