Under Construction
Unity15 min192 views

Boxing in Unity

Minh Khoa

Minh Khoa

Author

🎯 1. What is boxing? (standard definition)

Boxing = the action of converting a value of a value type (int, float, bool, struct…) into an object (a reference type).

In other words, C## wraps the value in an “object box” on the heap.

Example:

int x = 5;
object obj = x;   // ← boxing xảy ra

x from a value type (stored on the stack) → copied into an object (stored on the heap).


🎯 2. What is unboxing?

Take the value out of the object:

object obj = 10;
int y = (int)obj;  // ← unboxing

🎯 3. Why is BOXING harmful in Unity?

(1) Boxing creates memory allocation → causes GC

When boxing, C## creates a new object on the heap.

→ Alloc

→ Then GC it has to be cleaned up → causing spikes, drops FPS.

In games, especially in the update loop → very dangerous.


(2) Happens implicitly → hard to detect

Example:

int x = 10;
Debug.Log(x);

There is boxing because Log receives the parameter as object.


(3) Boxing occurs when using an interface

If a struct implements an interface → calling the interface method → BOX.

public interface IAttack { void Do(); }

public struct Sword : IAttack
{
    public void Do() { }
}

IAttack atk = new Sword();  // boxing!

(4) Boxing when using a generic without good constraints

Example:

void Print<T>(T value)
{
    Debug.Log(value);  // boxing nếu value là struct
}


(5) LINQ often causes boxing

LINQ to Object creates delegates, iterators → allocation + boxing.


🎯 4. Some common boxing examples in Unity


❌ Example 1: Debug.Log

int score = 10;
Debug.Log(score); // boxing

How to fix:

Debug.Log($"{score}"); // không boxing (string format)

❌ Example 2: Struct in List<object>

List<object> list = new();
list.Add(5); // boxing

❌ Example 3: Using an interface with a struct

IMovement mover = new MovementStruct(); // boxing

❌ Example 4: foreach with struct enumeration

foreach (var item in myStructList) { ... }
// nếu enumerator là struct → có thể boxing tùy implement

❌ Example 5: Event with a struct argument

Action<MyStruct> onChange;
onChange(myStruct); // có thể boxing

🎯 5. How can boxing be avoided?


✔ 1. Avoid using object to hold value types

Wrong:

object obj = 5;

Correct:

int x = 5;

✔ 2. Avoid interfaces if the struct implements an interface

Use generics instead.

*Generic (or generic programming) is not a specific data type (like the above, but is the concept of parameterized data typesintstring)parameterized types**. It allows defining classes(class)**, interfaces (interface)and methods (method) with unspecified data types, helping source code be flexible, highly reusable, and tightly controlled for errors at compile time (Wrong:) Correct:

→ cast to string to avoid boxing

IAttack atk = new Sword();

✔ 4. Optimize systems using structs

void Perform<T>(T atk) where T : IAttack
{
    atk.Do();
}

✔ 3. Debug.Log job system,

Debug.Log(score.ToString());

/ Burst entirely (no boxing ECS)

ECS ✔ 5. Avoid boxing in Dictionary key If the key is a struct → boxing may occur when.


overrides are poor.

  1. How can you tell if there is boxing in the code? GetHashCode() Unity Editor:

🎯 Enable

Profiler →

  • Allocations Allocations? Actually source says Alloc. Need exact translation of segment 77/78. Let's correct final JSON? Can't. Need valid JSON. Let's provide Alloc. We included an extra note accidentally. Need proper JSON only. Let's reissue clean.}]}】{ GC title_segments
  • Or enable Deep Profile

If each frame has:

System.Object
System.Int32
System.ValueType

→ that is BOXING.


🎯 7. Ultra-memorable summary

BOXING = struct → object → creates garbage → causes GC → drop FPS

Unity fears most GC → avoid boxing in:

  • Update()
  • LateUpdate()
  • FixedUpdate()
  • UI event spam
  • DOTS / Jobs
  • Network serialization