You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit e38573c
Browse filesBrowse the repository at this point in the historyBrowse files
Reclaim deleted mjSpec elements automatically via reference counting
Fixes#2882.
Previously, `mjCModel::operator-=(mjsElement*)` pushed deleted elements onto `detached_` without calling `Release()`, deferring reclamation until `~mjCModel()` (`mj_deleteSpec`) so Python handles to deleted elements would not become dangling pointers when passed to `model.bind` / `data.bind`. In workflows that repeatedly added and deleted elements or subtrees on a long-lived `mjSpec`, memory grew unbounded.
- Remove `mjCModel::detached_` and call `Release()` immediately when removing elements in `mjCModel::operator-=(mjsElement*)`.
- Set `id = -1` before `Release()` in `RemoveFromList`, `RemovePlugins`, and `operator-=(const mjCDef&)` so implicitly removed elements also report invalid IDs.
- Add intrusive reference counting (`AddRef` / `Release`) to `mjCDef` and use `Release()` on `mjCWrap` in `~mjCTendon()`.
- Add `MjsElementRef<T>` custom pybind11 holder for `Mjs*` wrapper types in `specs.cc` using internal `_mjPRIVATE_addRefElement` / `_mjPRIVATE_releaseElement` entry points so C++ elements stay alive while referenced by Python variables and are freed automatically upon Python GC.
PiperOrigin-RevId: 985105555
Change-Id: I8ffc0064ff56920c96135feb73e75cf6073d12e6
0 commit comments