TGViewer
Лаборатория Лиса Лаборатория Лиса @foxfoxcsharp · 79 subscribers
Post #8 95
Работа с классами в Job System: Магия указателей и GC Handle
Взмахивает лапой

Предисловие
В предыдущем посте мы рассмотрели работу со структурами в Job System. Сегодня мы пойдём дальше и покажем, как можно использовать классы в Jobs, обходя стандартные ограничения Unity.

Суть метода
Основная идея заключается в использовании GCHandle для получения стабильного указателя на управляемый объект:

// В основном потоке
var handle = GCHandle.Alloc(testClass, GCHandleType.Pinned);
classPtr = (IntPtr)handle;

// В Job'е
GCHandle handle = GCHandle.FromIntPtr(classPtr);
TestClassForJob obj = (TestClassForJob)handle.Target;


Преимущества подхода:

Нет необходимости копировать данные между потоками
Сохраняется вся функциональность классов (наследование, полиморфизм)
Чистый и понятный код
Прямой доступ к данным без маршалинга
Ограничения и особенности


Burst компиляция:
В редакторе (Mono) работает без проблем
В билде с IL2CPP может потребоваться отключение Burst для таких jobs
Теряем производительность Burst, но выигрываем в удобстве разработки

Безопасность:
Объект "закреплён" в памяти (pinned)
GC не может его перемещать
Важно правильно освобождать GCHandle
IL2CPP специфика:
IL2CPP совместим с данным подходом
Производительность может отличаться от Mono
Требуется дополнительное тестирование в Development Build
Пример использования
public class TestJobClass : MonoBehaviour
{
[SerializeField] private TestClassForJob testClass;
private IntPtr classPtr;
private JobHandle jobHandle;

void Start()
{
// Закрепляем объект в памяти
var handle = GCHandle.Alloc(testClass, GCHandleType.Pinned);
classPtr = (IntPtr)handle;

var job = new ManagedTestJob { classPtr = classPtr };
jobHandle = job.Schedule();
}

void OnDestroy()
{
jobHandle.Complete();
// Важно освободить handle!
if (classPtr != IntPtr.Zero)
{
GCHandle.FromIntPtr(classPtr).Free();
}
}
}


Производительность
Несмотря на отсутствие Burst компиляции, этот метод всё равно даёт преимущества:

Нет overhead на копирование данных
Меньше нагрузка на сборщик мусора
Прямой доступ к данным быстрее, чем маршалинг
Заключение

Этот эксперимент, как и предыдущий со структурами, показал отличные результаты! Мы получили рабочий способ использования классов в Job System, который особенно полезен когда:

Важнее удобство разработки, чем максимальная производительность
Требуется сохранить возможности ООП
Нужно избежать копирования больших объёмов данных
Гордо виляет хвостом

⚠️ Важно помнить:

Всегда освобождайте GCHandle
Тестируйте в реальных условиях (IL2CPP build)
Следите за правильным закрытием jobs перед освобождением handle

#ЛисыПишутКод #CSharp #Unity #GameDev #Optimization #MultiThreading #UnsafeCode #UnityJobs #BurstCompiler #Programming
  • 👍 1
More from @foxfoxcsharp
  1. Oct 7, 2026Вот более щедящий режим, тут хотя бы уже видно на каком моменте уже моделька начинает... Я…
  2. Oct 7, 2026Я тут накатил еще моделей, самая большая которая мне понравилась по уму и качеству и по ск…
  3. Oct 7, 2026Последние результаты ГЕНЕРАЦИЯ, ток/с модель 2k 8k 16k 32k 64k 128k ----------------------…
  4. Oct 6, 2026Ну в общем === qwen3.8:27b === загрузка: 116.0 с, 52% на GPU запуск 1: генерация 3.4 ток/с…
  5. Oct 6, 2026Продолжаю эксперементировать с гнейронками, накатил относительно свежие модельки (До этого…
  6. Oct 6, 2026Может быть мне человек это сказал для успокоения, но тем не менее, он высказал свое мнение…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →