Skip to content

Run processes without forced GC or a login shell - #32

Open
lm-sousa wants to merge 3 commits into
masterfrom
clava-optimizations
Open

Run processes without forced GC or a login shell#32
lm-sousa wants to merge 3 commits into
masterfrom
clava-optimizations

Conversation

@lm-sousa

@lm-sousa lm-sousa commented Sep 4, 2026

Copy link
Copy Markdown
Member

Every SpecsSystem.runProcess() call paid ~60 ms of overhead: a forced System.gc() before every fork (added as an experiment in 2018 to shrink fork memory) and, on Linux, a rewrap of the argv into bash -l -c (added in 2021). The wrapper also re-sourced login profiles on top of the inherited environment and broke argument fidelity with a naive space-escaping hack.

This removes both. ProcessBuilder children already inherit the JVM's full environment, user, and working directory at fork/exec — strictly closer to the parent than the wrapper, which a probe showed mutating PATH (duplicate entry from profile re-sourcing). Automatic garbage collection still runs; only the forced full collection was removed. The Windows cmd /c branch is untouched, and all in-tree callers pass plain argv.

Measured impact (Clava-JS test suite, 155 passed | 9 skipped in every run, six measured runs): median 111.79 s → 47.60 s (−64.19 s, 57.4%); Welch two-sample t-test vs the pre-change distribution: t(6.28) = 16.51, p = 0.0000021, 95% CI [51.28, 68.90] s. Per-launch probe: 60.29 ms → 7.65 ms (echo launch, 200 iterations). The suite performs on the order of a thousand process launches per run.

Also removes the GC call's per-launch measurement logging introduced with the same experiment.

Introduced in 530a468 as an experiment to reduce fork memory.
Measured at 50s of GC pauses in a 98s test run vs 0.14s with
automatic GC only. Automatic GC still runs; removing this does
not disable collection.
Drop the bash -l -c wrapper added in 44d1d93. The wrapper added
~50ms per launch for shell parsing, broke argument fidelity (naive
space escaping), and re-sourced login profiles over the inherited
environment instead of carrying it faithfully. ProcessBuilder
children already inherit the JVM's full environment, user, and
working directory. All in-tree callers pass plain argv; shell
semantics for string commands are no longer supported on Linux.
@lm-sousa
lm-sousa force-pushed the clava-optimizations branch 3 times, most recently from da92ff7 to 21dc912 Compare September 5, 2026 01:23
With direct argv, a missing or non-executable command now throws from
runProcess(), as its javadoc always documented ('If there is any
problem with the process, throws an exception') - the removed shell
wrapper used to mask launch failures as exit code 127. Handle the
launch failure where graceful failure is the intent:

- SpecsGraphviz: dot being absent is a normal condition, so checkDot()
  returns false and renderDot() logs instead of crashing.
- ProcessExecution: the jobs framework is built on return codes with
  no exception handling, so run() reports the failed launch as
  exit code 127 instead of propagating.

This also restores SpecsSystem.isCommandAvailable()'s intended
behavior: it detects missing commands by catching the launch
exception, which the wrapper's masking previously defeated.
@lm-sousa
lm-sousa force-pushed the clava-optimizations branch from 21dc912 to 44ab197 Compare September 5, 2026 01:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant