Quick answer: Unity ParticleSystem OnParticleCollision allocating GC pressure each frame? GetCollisionEvents needs a pre-allocated list - reuse one instead of passing null.

GC alloc spike of 4KB per frame from a single collision particle system. Player feels per-second hitches.

Pre-allocate the list

List<ParticleCollisionEvent> events = new(256);
void OnParticleCollision(GameObject other) {
  ps.GetCollisionEvents(other, events);
}

Class field. Reused per call; no per-frame allocation.

Or use the array overload

GetCollisionEvents(GameObject, ParticleCollisionEvent[]) takes a buffer you provide. Returns count; no resizing needed.

Profile with Allocator

Profiler > GC.Alloc per call site. Any non-zero on a hot path is suspect.

“Unity APIs that return collections allocate by default. Reusable buffers are the cost of allocation hygiene.”

Audit Get* APIs across your codebase. Almost all have a buffer-accepting overload that costs nothing once you wire it up.