Skip to content

Commit 94544f9

Browse files
committed
max memory trigger
1 parent b532344 commit 94544f9

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

src/fsharp/vs/service.fs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ module EnvMisc =
6262

6363
let projectCacheSizeDefault = GetEnvInteger "mFSharp_ProjectCacheSizeDefault" 3
6464
let frameworkTcImportsCacheStrongSize = GetEnvInteger "mFSharp_frameworkTcImportsCacheStrongSizeDefault" 8
65-
let maxMBDefault = GetEnvInteger "mFSharp_maxMB" 2000
65+
let maxMBDefault = GetEnvInteger "mFSharp_maxMB" 1700
6666

6767
//----------------------------------------------------------------------------
6868
// Methods
@@ -2514,7 +2514,7 @@ type BackgroundCompiler(projectCacheSize, keepAssemblyContents, keepAllBackgroun
25142514
scriptClosureCache.Clear())
25152515

25162516
member bc.DownsizeCaches() =
2517-
reactor.EnqueueOp (fun () ->
2517+
reactor.EnqueueAndAwaitOpAsync (fun () ->
25182518
incrementalBuildersCache.Resize(keepStrongly=1, keepMax=1)
25192519
frameworkTcImportsCache.Downsize()
25202520
scriptClosureCache.Resize(keepStrongly=1, keepMax=1))
@@ -2950,7 +2950,7 @@ type FSharpChecker(projectCacheSize, keepAssemblyContents, keepAllBackgroundReso
29502950
areSame=AreSameForChecking3,
29512951
areSameForSubsumption=AreSubsumable3)
29522952

2953-
let mutable downsizedCaches = false
2953+
let mutable maxMemoryReached = false
29542954
let mutable maxMB = maxMBDefault
29552955
let maxMemEvent = new Event<unit>()
29562956

@@ -2977,7 +2977,7 @@ type FSharpChecker(projectCacheSize, keepAssemblyContents, keepAllBackgroundReso
29772977

29782978
member ic.ParseFileInProject(filename, source, options) =
29792979
async {
2980-
ic.CheckDownsizeCaches()
2980+
ic.CheckMaxMemoryReached()
29812981
match parseFileInProjectCache.TryGet (filename, source, options) with
29822982
| Some res -> return res
29832983
| None ->
@@ -3011,23 +3011,25 @@ type FSharpChecker(projectCacheSize, keepAssemblyContents, keepAllBackgroundReso
30113011
parseFileInProjectCache.Clear()
30123012
backgroundCompiler.ClearCaches()
30133013

3014-
member ic.CheckDownsizeCaches() =
3015-
if not downsizedCaches && System.GC.GetTotalMemory(false) > int64 maxMB * 1024L * 1024L then
3014+
member ic.CheckMaxMemoryReached() =
3015+
if not maxMemoryReached && System.GC.GetTotalMemory(false) > int64 maxMB * 1024L * 1024L then
30163016
// If the maxMB limit is reached, drastic action is taken
30173017
// - reduce strong cache sizes to a minimum
3018-
downsizedCaches <- true
3018+
backgroundCompiler.WaitForBackgroundCompile() // flush AsyncOp
3019+
maxMemoryReached <- true
30193020
parseAndCheckFileInProjectCachePossiblyStale.Resize(keepStrongly=1)
30203021
parseAndCheckFileInProjectCache.Resize(keepStrongly=1)
30213022
braceMatchCache.Resize(keepStrongly=1)
30223023
parseFileInProjectCache.Resize(keepStrongly=1)
3023-
backgroundCompiler.DownsizeCaches()
3024+
backgroundCompiler.DownsizeCaches() |> Async.RunSynchronously
30243025
maxMemEvent.Trigger( () )
30253026

30263027
/// This function is called when the entire environment is known to have changed for reasons not encoded in the ProjectOptions of any project/compilation.
30273028
/// For example, the type provider approvals file may have changed.
30283029
//
30293030
// This is for unit testing only
30303031
member ic.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() =
3032+
backgroundCompiler.WaitForBackgroundCompile() // flush AsyncOp
30313033
ic.ClearCaches()
30323034
System.GC.Collect()
30333035
System.GC.WaitForPendingFinalizers()
@@ -3068,7 +3070,7 @@ type FSharpChecker(projectCacheSize, keepAssemblyContents, keepAllBackgroundReso
30683070
member ic.CheckFileInProject(parseResults:FSharpParseFileResults, filename:string, fileVersion:int, source:string, options:FSharpProjectOptions, ?isResultObsolete, ?textSnapshotInfo:obj) =
30693071
let (IsResultObsolete(isResultObsolete)) = defaultArg isResultObsolete (IsResultObsolete(fun _ -> false))
30703072
async {
3071-
ic.CheckDownsizeCaches()
3073+
ic.CheckMaxMemoryReached()
30723074
let! checkAnswer = backgroundCompiler.CheckFileInProject(parseResults,filename,source,options,isResultObsolete,textSnapshotInfo)
30733075
ic.RecordTypeCheckFileInProjectResults(filename,options,parseResults,fileVersion,Some checkAnswer,source)
30743076
return checkAnswer
@@ -3080,15 +3082,15 @@ type FSharpChecker(projectCacheSize, keepAssemblyContents, keepAllBackgroundReso
30803082
let cachedResults = parseAndCheckFileInProjectCache.TryGet((filename,source,options))
30813083
let (IsResultObsolete(isResultObsolete)) = defaultArg isResultObsolete (IsResultObsolete(fun _ -> false))
30823084
async {
3083-
ic.CheckDownsizeCaches()
3085+
ic.CheckMaxMemoryReached()
30843086
let! parseResults, checkAnswer, usedCachedResults = backgroundCompiler.ParseAndCheckFileInProject(filename,source,options,isResultObsolete,textSnapshotInfo,cachedResults)
30853087
if not usedCachedResults then
30863088
ic.RecordTypeCheckFileInProjectResults(filename,options,parseResults,fileVersion,Some checkAnswer,source)
30873089
return (parseResults, checkAnswer)
30883090
}
30893091

30903092
member ic.ParseAndCheckProject(options) =
3091-
ic.CheckDownsizeCaches()
3093+
ic.CheckMaxMemoryReached()
30923094
backgroundCompiler.ParseAndCheckProject(options)
30933095

30943096
/// For a given script file, get the ProjectOptions implied by the #load closure

tests/service/MultiProjectAnalysisTests.fs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,24 @@ let ``Test active patterns' XmlDocSig declared in referenced projects`` () =
715715

716716
//------------------------------------------------------------------------------------
717717

718+
719+
720+
[<Test>]
721+
let ``Test max memory gets triggered`` () =
722+
let checker = FSharpChecker.Create()
723+
let reached = ref false
724+
checker.MaxMemoryReached.Add (fun () -> reached := true)
725+
let wholeProjectResults = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunSynchronously
726+
reached.Value |> shouldEqual false
727+
checker.MaxMemory <- 0
728+
let wholeProjectResults2 = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunSynchronously
729+
reached.Value |> shouldEqual true
730+
let wholeProjectResults3 = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunSynchronously
731+
reached.Value |> shouldEqual true
732+
733+
734+
//------------------------------------------------------------------------------------
735+
718736
#if FX_ATLEAST_45
719737

720738
[<Test>]

0 commit comments

Comments
 (0)