Skip to content

Builds of large DDK-based workspaces are slower and retain more memory since #1405 #1545

Open

Description

@joaodinissf

Since #1405 turned Scope and Export into Xbase / JvmModelInferrer languages, Eclipse builds of large DDK-based workspaces allocate much more, keep more memory alive, and do more work after git branch switches. In a long IDE session this compounds into GC pressure, and the effect seems strongest on Windows with Microsoft Defender scanning every file the builders write.

Measurements

These are headless Eclipse runs on a synthetic downstream-shaped workspace (L: 98 projects, 59 .scope, 59 .export, 939 .xtend), with the stock Xtext builder, alternating git checkout between two branches that differ only in Java/Xtend files. There are 2 runs per variant on macOS. Wall times were too noisy on that machine to quote, so the table shows counters and memory.

1e0a5c8 (2026-06-29) v19.2.0 master + fixes below
full build: allocated 50.5 GB 75.2 GB (+49%) 61.2 GB
full build: live set afterwards 402 MB 634 MB 398 MB
per branch switch: allocated 6.1 GB 6.8 GB 6.1 GB
per branch switch: .export re-processed 0 2 0
live-set growth per switch (20 switches, M workload) 0.3 MB 7.9 MB 0.3 MB

Causes found and fixes (draft PRs)

  • A thread-local leak in ExportJvmModelInferrer keeps the last export resource's whole builder resource set alive. Fixed in the R12 PR.
  • Scope/Export generation rebuilds an all-EPackages type resolver per expression, a project class loader per method body, and uncached genmodel lookups. Fixed in the Tier A PR, with byte-identical output.
  • Java-only changes re-queue and regenerate .export files, because Xbase records the EMF interfaces as imported names. Fixed in the R1 PR, which is for discussion.
  • What remains after these fixes is about +20% full-build allocation. That is the inherent cost of Scope/Export being full Xbase languages. Whether they need to be is a separate design question.

A before/after measurement of each PR on the affected Windows machine is in progress. The PRs stay drafts until it is in.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LgVRfQCTxSDwGrN8J5s6fd

Activity

  1. joaodinissf commented on Sep 25, 2026

    @joaodinissf
    CollaboratorAuthor

    Draft PRs:

    Each is based on master on its own. A before/after benchmark of each on the affected Windows machine is running; the PRs stay drafts until its results are in.

    🤖 Generated with Claude Code

  2. joaodinissf commented on Sep 25, 2026

    @joaodinissf
    CollaboratorAuthor

    Benchmark results from the affected platform (Windows 11, 16 cores, Microsoft Defender on), using the same synthetic workspace and harness as the macOS numbers above: 33 runs, each started only on a quiet machine, 0 error markers.

    1. macOS vs Windows (@gerdleon): the same workload, harness and DDK builds (M workload, stock builder, 4 GB heap; medians over 3 quiet rounds on both machines):

    macOS (Apple Silicon, 14 cores) Windows 11 + Defender (16 cores) Windows / macOS
    full build, master 30.7 s 122.4 s 4.0×
    branch switch, master 3.04 s 13.6 s 4.5×
    GC per branch switch, master 26 ms 96 ms 3.7×
    branch switch, master + the three PRs 2.75 s (−10%) 13.6 s (within noise)
    files processed / written, .export re-processed, live set identical identical

    The build does exactly the same work on both machines; Windows spends about 4× the wall time doing it. Defender's engine was busy at 21–51% of a core throughout. Proportionally the DDK regression is the same on both (at L a full build got ~60% slower from 2026-06-29 to v19.2.0: +169 s on Windows, 288 → 457 s; +52 s on macOS, 89 → 141 s, indicative only), but in absolute terms it costs about 3× more on Windows.

    2. The regression at scale and the fixes (@rubenporras): L workload (98 projects, 59 .scope/.export, 939 .xtend; stock Xtext builder), on Windows:

    2026-06-29 v19.2.0 master + #1546 #1547 #1548
    full build 288 s 457 s (+58%) 301 s
    branch switch (Java-only change) 32.9 s 38.2 s 27.6 s
    allocated per full build 52.8 GB 78.2 GB 63.9 GB
    live set after the build 402 MB 633 MB 396 MB

    (master is 20 commits past v19.2.0, so the last column is not fix-only; point 3 is.)

    3. Fix-only, under heap pressure (master vs master + the three PRs; M workload, 1.2 GB heap, 20 branch switches): full build 154 → 110 s (−29%), branch switch 15.3 → 11.3 s (−26%), first switch 19.7 → 12.4 s (−37%), live-set growth 7.8 → 0.2 MB per switch, peak working set 1.63 → 1.36 GB.

    4. At a comfortable 4 GB heap the per-PR wall-time differences on Windows are within noise; the allocation, live-set and files-written effects reproduce the macOS numbers exactly. The fixes pay off where large downstream workspaces live: big workspaces, tight heaps, Windows.

    Still open: at L, a full build still allocates ~20% more than before #1405. That's the inherent cost of Scope/Export being Xbase languages, and worth a separate discussion.

    🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions