# Description
Consolidate the complete B01/B02 NodeState memory work into one PR.
- Replace eager cold-path NodeState locks with lazy canonical
publication and update
the event-monitor counter atomically.
- Store six design-metadata properties and three security properties in
separate lazy
private bags while preserving public APIs, null/empty distinctions,
masks, copying
and existing serialization behavior.
- Avoid allocating the ReportEvent scheduling closure when the
async-dispatch path is
unused.
- Retain the logger factory's category logger directly, avoiding a
redundant typed
wrapper on telemetry initialization.
- Keep Variant at 24 bytes while removing eligible outer boxes for
QualifiedName,
NodeId, NET8+ ByteString and text-only LocalizedText values.
- Add reproducible allocation/layout/occupancy fixtures, real registered
and monitored
populations, reference contracts, generated-consumer coverage and
NativeAOT cases.
## Measured allocation changes
Matched .NET 10.0.11 x64 observations against the integrated master
baseline:
| Construction/assignment | Master | This PR |
|---|---:|---:|
| Bare/minimal object | 824 B | 640 B |
| Bare/minimal variable | 1160 B | 976 B |
| Variable with both optional groups populated or reset | 1160 B | 1088
B |
| Variable with a shared ByteString value | 1192 B | 976 B |
Separate paired measurements show:
- telemetry initialization: 24 B typed-logger wrapper removed;
- eligible QualifiedName, NodeId and ByteString Variant construction: 32
B to 0 B;
- eligible text-only LocalizedText Variant construction: 40 B to 0 B;
- variable attributes read into caller-provided Variant destinations:
136 B to 0 B.
These are runtime-specific per-operation observations, not additive
whole-server
savings. Optional bags retain their documented populated/high-water
premiums and are
not reclaimed on reset.
## Reference-storage decision
A complete private indexed reference backend and a sorted-traversal
alternative were
measured, but both changed the existing filtered hash-index enumeration
order. They
were rejected despite lower memory use. The production reference backend
remains
unchanged; strengthened ordering, identity, serialization and
concurrency contracts
are retained. Adaptive small-set storage remains deferred.
## Consolidation
This PR now contains all changes from #4451 and the former narrower
#4452 branch.
Every #4452 changed path was present in #4451; after merging, the #4451
head
`836e45226` is a direct ancestor of this branch. #4451 is closed as
superseded.
Draft #4425 remains unchanged and is also superseded by this
consolidated work.
## Review feedback
- Removed the standalone Variant storage document and its README entry.
- Made the raw NodeId constructor private; the documented internal
`GetRawState`/`SetRawState` bridge is explicitly Variant-only and must
never become
public.
- Marked the two 32-thread counter tests non-parallel.
- Added 10-second timeouts to the concurrent browse benchmark's main and
worker
barriers and completion waits.
- Migrated the registered-population fixture to the current async
`SealAsync` API.
All review threads on #4451 and #4452 were replied to with the action
and fix commit,
then resolved.
## Related issues
- Related to #4275.
- Supersedes #4425 and #4451.
## Validation
- Consolidated Types/Core/Server selection: **1241 passed** on net10.0.
- Consolidated Types/Core/Server selection: **1238 passed** on net48.
- Focused #4451 feedback selection: **189 passed** on net10.0 and **187
passed**
on net48.
- Earlier integrated NativeAOT validation passed **163/163** cases
across the main,
MCP and Historian applications; current PR CI provides the authoritative
final
merged-source native validation.
The first #4452 CI run was blocked by merge conflicts. Seven later jobs
completed
their tests but encountered a shared artifact-service HTTP 403 while
uploading
results; no workflow or test was weakened to mask that infrastructure
failure.
Generated `report.*.json` crash artifacts remain untracked and are not
part of this PR.
## Checklist
- [ ] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have added tests that prove the changes and improve coverage.
- [x] I have added the necessary current-behavior documentation.
- [ ] I have verified that the fresh consolidated CI run introduces no
build or analyzer warnings.
- [ ] I ran the complete UA.slnx suite locally on net48 and net10.0 with
no failures.
- [ ] I fixed all failing and flaky CI tests and all CodeQL warnings.
- [x] I have addressed all PR feedback received.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d2569e2e-7115-4969-bb44-8159e302b450