-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restart presentation compilers if memory is low
I have noted during long editing sessions (lasting several days, typically) that memory can get full because the Dotty compiler has some space leaks. The leaks looks really hard to fix, and we don't know yet whether it's at all possible. To mitigate the leaks, this commit makes the language server watch available memory, and, if it is low (i.e. free memory after a GC < 10% of maximal available) restart all interactive drivers. This will free all memory of the compiler(s) except the shared nametable. There's a stressTest option in `Memory.scala`, which, when turned on, causes a restart every 10 editing actions. I verified that the compiler stays functional and reasonably responsive in that mode.
- Loading branch information
Showing
4 changed files
with
97 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
language-server/src/dotty/tools/languageserver/Memory.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package dotty.tools | ||
package languageserver | ||
|
||
object Memory { | ||
|
||
/** Memory is judged to be critical if after a GC the amount of used memory | ||
* divided by total available memory exceeds this threshold. | ||
*/ | ||
val UsedThreshold = 0.9 | ||
|
||
/** If total available memory is unknown, memory is judged to be critical if | ||
* after a GC free memory divided by used memory is under this threshold. | ||
*/ | ||
val FreeThreshold = 0.1 | ||
|
||
/** Turn this flag on to stress test restart capability in compiler. | ||
* It will restart the presentation compiler after every 10 editing actions | ||
*/ | ||
private final val stressTest = false | ||
private var stressTestCounter = 0 | ||
|
||
/** Is memory critically low? */ | ||
def isCritical(): Boolean = { | ||
if (stressTest) { | ||
stressTestCounter += 1 | ||
if (stressTestCounter % 10 == 0) return true | ||
} | ||
val runtime = Runtime.getRuntime | ||
def total = runtime.totalMemory | ||
def maximal = runtime.maxMemory | ||
def free = runtime.freeMemory | ||
def used = total - free | ||
def usedIsCloseToMax = | ||
if (maximal == Long.MaxValue) free.toDouble / used < FreeThreshold | ||
else used.toDouble / maximal > UsedThreshold | ||
usedIsCloseToMax && { runtime.gc(); usedIsCloseToMax } | ||
} | ||
|
||
def stats(): String = { | ||
final val M = 2 << 20 | ||
val runtime = Runtime.getRuntime | ||
def total = runtime.totalMemory / M | ||
def maximal = runtime.maxMemory / M | ||
def free = runtime.freeMemory / M | ||
s"total used memory: $total MB, free: $free MB, maximal available = $maximal MB" | ||
} | ||
} |