Skip to content

Mem leak fix#60

Open
lygstate wants to merge 2 commits into
lvgl:masterfrom
lvgljs:mem-leak-fix
Open

Mem leak fix#60
lygstate wants to merge 2 commits into
lvgl:masterfrom
lvgljs:mem-leak-fix

Conversation

@lygstate

@lygstate lygstate commented Jun 14, 2026

Copy link
Copy Markdown

Summary by cubic

Fixes native and React reconciler memory leaks by properly detaching and deleting components. Prevents comp_map growth, double frees, and orphaned instances; adds leak probes and a CLI test runner with faster builds.

  • Bug Fixes

    • Native: make close() idempotent in WRAPPED_JS_CLOSE_COMPONENT (guard s/s->comp, delete BasicComponent, set nullptr); make removeChild a no-op (no reparenting; JS owns teardown); destructor resets styles, removes event callback, deletes LVGL instance if valid, then nulls it.
    • React reconciler: use instanceMap.set/get/delete; track host children; detachInstance recursively closes children before the parent, guards double-detach, unregisters events, clears style, then close(); applied in removeChild, removeChildFromContainer, and detachDeletedInstance.
  • New Features

    • Leak probes: add RenderUtil.getCompMapSize() and updateTestTree() in lvgljs-ui.
    • CLI runtime tests (binding-leak, calendar-leak) and parallel esbuild for faster test builds.

Written for commit f14e6e2. Summary will update on new commits.

Review in cubic

Closes: #19

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 12 files

Re-trigger cubic

Null comp after delete so a second close() or finalizer path does not
double-free the same BasicComponent.

Native
- component.hpp: WRAPPED_JS_CLOSE_COMPONENT guards s->comp
@lygstate lygstate force-pushed the mem-leak-fix branch 2 times, most recently from 1f8ba4a to 1ec181f Compare June 14, 2026 01:16
React unmount leaked comp_map entries and JS shells; instanceMap used
bracket syntax on a Map. Reconciler now tracks host children, closes
children before parents, and calls close() on detach.

Reconciler (src/render/react/core/reconciler/index.js)
- instanceMap: .set() / .get() / .delete(); detachInstance with _detached guard
- _hostChildren tracking; recursive child detach before parent close
- removeChild, removeChildFromContainer, detachDeletedInstance call detachInstance
- Teardown order owned by JS (children close before parent); comments document contract

Native (src/render/native/core/basic/comp.cpp)
- removeChild: bookkeeping only (parent_instance); no reparent to window root
- destructor: style reset, lv_obj_remove_event_cb, lv_obj_del on close() path
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.

Memory leak keeps growing when mounting / unmounting elements

1 participant