-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Summary
The Kotlin Language Server (KLS) is built on IntelliJ IDEA's platform. Each KLS instance creates an idea-system* temporary directory under /tmp. These directories are never cleaned up after the language server shuts down, causing unbounded accumulation across test runs.
Observed Impact
On a developer machine with /tmp mounted as tmpfs (RAM-backed — the default on modern Linux systems), repeated test runs accumulated:
329 x idea-system*/ = 30 GiB in RAM
/tmp (tmpfs): 36 GiB used total
Each KLS instance produces ~52 MB in its idea-system* directory. After 329 test sessions the entire tmpfs was nearly exhausted, starving the system of RAM and swap.
Root Cause
IntelliJ's platform runtime defaults to creating its system directory at /tmp/idea-system<random>/ when no explicit idea.system.path JVM property is set. The KotlinLanguageServer currently passes JAVA_TOOL_OPTIONS (heap size) but does not redirect this path:
# src/solidlsp/language_servers/kotlin_language_server.py
def create_launch_command_env(self) -> dict[str, str]:
env["JAVA_TOOL_OPTIONS"] = jvm_options # only -Xmx2G by default
return envThe stop() / _shutdown() implementation in SolidLanguageServer terminates the process but performs no filesystem cleanup.
Suggested Fix
Two complementary changes in KotlinLanguageServer:
-
Redirect
idea.system.pathto a location we control (e.g. insidels_resources_diror atempfile.mkdtemp()created at startup) by appending-Didea.system.path=<path>toJAVA_TOOL_OPTIONS. -
Clean up on stop — override
stop()inKotlinLanguageServerto delete the directory after the process terminates.
Example sketch:
import tempfile, shutil
class KotlinLanguageServer(SolidLanguageServer):
def __init__(self, ...):
self._idea_system_dir = tempfile.mkdtemp(prefix="serena-idea-system-")
...
def create_launch_command_env(self) -> dict[str, str]:
env = super().create_launch_command_env()
jvm_options = env.get("JAVA_TOOL_OPTIONS", "")
env["JAVA_TOOL_OPTIONS"] = f"{jvm_options} -Didea.system.path={self._idea_system_dir}".strip()
return env
def stop(self, shutdown_timeout: float = 2.0) -> None:
super().stop(shutdown_timeout)
if hasattr(self, "_idea_system_dir"):
shutil.rmtree(self._idea_system_dir, ignore_errors=True)Alternatively the directory can live under ls_resources_dir/kotlin_language_server/system/ — a persistent but bounded cache — if keeping the IntelliJ index across sessions is desirable (faster restarts). In that case no cleanup is needed, but its size should be documented.
Environment
- Platform: Linux (x86-64),
/tmpistmpfs - KLS version: 261.13587.0 (default bundled)
- Serena branch:
fix/kill-gradle-daemons-on-shutdown
Related
- PR [SCALA LSP] Do not reinstall metals if it is globally available on system #1076 / PR Dashboard: Replace automatic banner rotation with random initial display and manual rotation #1077 (Gradle daemon cleanup on shutdown — similar class of JVM process hygiene issues)