Copyright © 2026 Unity Technologies
Thanks for the detailed probe. The allocator argument is validated, and has been since this API shipped, so there is no defect here. We reproduced your run and the log contains the evidence against the leak claim. What actually happens Passing an invalid allocator to CreateSnapshot logs a warning and returns a snapshot that was never created. This is the documented behaviour: the allocator parameter must be Temp, TempJob or Persistent, and the return documentation states the snapshot is not created if the world or allocator is invalid. No memory is allocated on that path. The warning is in the log file you captured, once per call, with a full stack trace: Unity.U2D.Physics.PhysicsWorld.CreateSnapshot was called with an invalid argument 'Allocator allocator'. The allocator must be `Temp`, `TempJob` or `Persistent`. Problems with the test 1. Your own probe reports that nothing was created. The P2 lines print anyCreated=False at every checkpoint, including the last one, while the delta climbs to 13845 KiB. Zero snapshots were created and memory still grew, so the growth is not snapshot memory. P1 told you the same thing: IsCreated=false, Length=0. 2. The growth is the warning messages. The check logs one warning with a stack trace per call. That is roughly 780 bytes of log text per iteration against roughly 1.35 KiB of measured growth per iteration. The remainder is the retained console entry and the associated strings. 3. Your log handler ignores warnings. It counts only Error, Assert and Exception. The rejection is a warning, so the "silent failure, no error log" conclusion comes from the filter rather than the engine. 4. Disposal of a non-created snapshot is a no-op, so the loop always reaches 10000 and the failure branch fires whether or not anything leaked. The threshold check cannot distinguish a leak from log volume. 5. Profiler.GetTotalAllocatedMemoryLong reports memory for the whole process, not for the call under test, so a delta measured around a loop is not attributable to that call. 6. Batch mode with executeMethod runs inside a single frame. Anything held for deferred release cannot be reclaimed until your method returns, so growth measured inside one uninterrupted loop is not evidence of a leak. 7. The expected result assumes an exception. This API reports invalid arguments with a warning and a default return value, and does not throw. That is consistent across the surface, including GetBodies in your P4 probe. Your P5 probe is the control P5 performs 50000 create and dispose round-trips with Allocator.Persistent and reports 266 KiB total. That is flat at five times the iteration count of P2, using the same world and the same call. The allocator path that actually allocates does not leak.
How to reproduce:
Actual result: The log contains "P2 FAIL: ... MiB retained after 10000 create+dispose with Allocator.None — unbounded native leak" and no exception is thrown for the invalid allocator
Expected result: An ArgumentException is thrown, or the "P2" allocated memory delta stays flat
Reproducible with: 6000.6.0f1, 6000.7.0a2, 6000.7.0a6
Could not test with: 6000.0.0f1, 6000.0.83f1, 6000.3.23f1, 6000.5.11f1, 6000.7.0a1 (PhysicsWorld.CreateSnapshot API does not exist)
Reproducible on: macOS 26.6.2 (M1 Max)
Not reproducible on: No other environments tested
Issues you vote on will appear here