You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -8,24 +16,24 @@ This is a design note on the FSharpChecker component and its caches. See also t
8
16
9
17
Each FSharpChecker object maintains a set of caches. These are
10
18
11
-
* ``scriptClosureCache`` - an MRU cache of default size ``projectCacheSize`` that caches the
19
+
* ``scriptClosureCache`` - an MRU cache of default size ``projectCacheSize`` that caches the
12
20
computation of GetProjectOptionsFromScript. This computation can be lengthy as it can involve processing the transitive closure
13
21
of all ``#load`` directives, which in turn can mean parsing an unbounded number of script files
14
22
15
-
* ``incrementalBuildersCache`` - an MRU cache of projects where a handle is being kept to their incremental checking state,
16
-
of default size ``projectCacheSize`` (= 3 unless explicitly set as a parameter).
17
-
The "current background project" (see the [FSharpChecker operations queue](queue.html))
23
+
* ``incrementalBuildersCache`` - an MRU cache of projects where a handle is being kept to their incremental checking state,
24
+
of default size ``projectCacheSize`` (= 3 unless explicitly set as a parameter).
25
+
The "current background project" (see the [FSharpChecker operations queue](queue.html))
18
26
will be one of these projects. When analyzing large collections of projects, this cache usually occupies by far the most memory.
19
27
Increasing the size of this cache can dramatically decrease incremental computation of project-wide checking, or of checking
20
28
individual files within a project, but can very greatly increase memory usage.
21
29
22
30
* ``braceMatchCache`` - an MRU cache of size ``braceMatchCacheSize`` (default = 5) keeping the results of calls to MatchBraces, keyed by filename, source and project options.
23
31
24
-
* ``parseFileCache`` - an MRU cache of size ``parseFileCacheSize`` (default = 2) keeping the results of ParseFile,
32
+
* ``parseFileCache`` - an MRU cache of size ``parseFileCacheSize`` (default = 2) keeping the results of ParseFile,
25
33
keyed by filename, source and project options.
26
34
27
-
* ``checkFileInProjectCache`` - an MRU cache of size ``incrementalTypeCheckCacheSize`` (default = 5) keeping the results of
28
-
ParseAndCheckFileInProject, CheckFileInProject and/or CheckFileInProjectIfReady. This is keyed by filename, file source
35
+
* ``checkFileInProjectCache`` - an MRU cache of size ``incrementalTypeCheckCacheSize`` (default = 5) keeping the results of
36
+
ParseAndCheckFileInProject, CheckFileInProject and/or CheckFileInProjectIfReady. This is keyed by filename, file source
29
37
and project options. The results held in this cache are only returned if they would reflect an accurate parse and check of the
30
38
file.
31
39
@@ -35,8 +43,8 @@ Each FSharpChecker object maintains a set of caches. These are
35
43
are all weak references, you can generally ignore this cache, since its entries will be automatically collected.
36
44
Strong references to binary readers will be kept by other FCS data structures, e.g. any project checkers, symbols or project checking results.
37
45
38
-
In more detail, the bytes for referenced .NET binaries are read into memory all at once, eagerly. Files are not left
39
-
open or memory-mapped when using FSharpChecker (as opposed to FsiEvaluationSession, which loads assemblies using reflection).
46
+
In more detail, the bytes for referenced .NET binaries are read into memory all at once, eagerly. Files are not left
47
+
open or memory-mapped when using FSharpChecker (as opposed to FsiEvaluationSession, which loads assemblies using reflection).
40
48
The purpose of this cache is mainly to ensure that while setting up compilation, the reads of mscorlib, FSharp.Core and so on
41
49
amortize cracking the DLLs.
42
50
@@ -46,8 +54,8 @@ Each FSharpChecker object maintains a set of caches. These are
46
54
47
55
Profiling the memory used by the various caches can be done by looking for the corresponding static roots in memory profiling traces.
48
56
49
-
The sizes of some of these caches can be adjusted by giving parameters to FSharpChecker. Unless otherwise noted,
50
-
the cache sizes above indicate the "strong" size of the cache, where memory is held regardless of the memory
57
+
The sizes of some of these caches can be adjusted by giving parameters to FSharpChecker. Unless otherwise noted,
58
+
the cache sizes above indicate the "strong" size of the cache, where memory is held regardless of the memory
51
59
pressure on the system. Some of the caches can also hold "weak" references which can be collected at will by the GC.
52
60
53
61
> Note: Because of these caches, you should generally use one global, shared FSharpChecker for everything in an IDE application.
@@ -58,13 +66,13 @@ Low-Memory Condition
58
66
59
67
Version 1.4.0.8 added a "maximum memory" limit specified by the `MaxMemory` property on FSharpChecker (in MB). If an FCS project operation
60
68
is performed (see `CheckMaxMemoryReached` in `service.fs`) and `System.GC.GetTotalMemory(false)` reports a figure greater than this, then
61
-
the strong sizes of all FCS caches are reduced to either 0 or 1. This happens for the remainder of the lifetime of the FSharpChecker object.
62
-
In practice this will still make tools like the Visual Studio F# Power Tools usable, but some operations like renaming across multiple
69
+
the strong sizes of all FCS caches are reduced to either 0 or 1. This happens for the remainder of the lifetime of the FSharpChecker object.
70
+
In practice this will still make tools like the Visual Studio F# Power Tools usable, but some operations like renaming across multiple
63
71
projects may take substantially longer.
64
72
65
-
By default the maximum memory trigger is disabled, see `maxMBDefault` in `service.fs`.
73
+
By default the maximum memory trigger is disabled, see `maxMBDefault` in `service.fs`.
66
74
67
-
Reducing the FCS strong cache sizes does not guarantee there will be enough memory to continue operations - even holding one project
75
+
Reducing the FCS strong cache sizes does not guarantee there will be enough memory to continue operations - even holding one project
68
76
strongly may exceed a process memory budget. It just means FCS may hold less memory strongly.
69
77
70
78
If you do not want the maximum memory limit to apply then set MaxMemory to System.Int32.MaxValue.
@@ -73,9 +81,9 @@ Summary
73
81
-------
74
82
75
83
In this design note, you learned that the FSharpChecker component keeps a set of caches in order to support common
76
-
incremental analysis scenarios reasonably efficiently. They correspond roughly to the original caches and sizes
84
+
incremental analysis scenarios reasonably efficiently. They correspond roughly to the original caches and sizes
77
85
used by the Visual F# Tools, from which the FSharpChecker component derives.
78
86
79
-
In long running, highly interactive, multi-project scenarios you should carefully
87
+
In long running, highly interactive, multi-project scenarios you should carefully
80
88
consider the cache sizes you are using and the tradeoffs involved between incremental multi-project checking and memory usage.
0 commit comments