Parte oficial do evento
Boa tarde. Trabalho como programador na Owlcat Games, que lançou um dos RPGs de computador russos de maior sucesso, o Pathfinder: Kingmaker, e atualmente está trabalhando em sua sequência, Pathfinder: Wrath of the Righteous. Ao portar o primeiro jogo do nosso estúdio no console, enfrentamos o problema de encontrar vazamentos de memória. Por vários motivos, as ferramentas padrão do mecanismo Unity e das plataformas de destino acabaram não sendo muito convenientes para lidar com vazamentos e, portanto, decidimos escrever nossa própria ferramenta, que discutirei a seguir.
Owlcat Mono Profiler foi projetado para investigar o uso de memória Mono em jogos Unity. Ele está disponível para todos na forma de binários compilados (no Windows) e código-fonte no Github . Ao contrário do criador de perfil Unity integrado, bem como do pacote Memory Profiler, ele não exige a captura de instantâneos do estado da memória, mas monitora constantemente o heap Mono, o que permite detectar não apenas vazamentos, mas também picos de alocação e alocações repetidas redundantes. Comparado a ferramentas específicas da plataforma, como o Memory Analyzer para PS4, ele exibe corretamente os eventos que ocorrem na memória coletada pelo lixo.
Nesse ponto, encerraremos as formalidades e passaremos para a história legal.
Uma falha fatal em todas as outras ferramentas
Tudo começou com o fato de que descobrimos que a memória em nosso jogo está vazando. Em um PC, isso não foi um problema, já que não flui como uma cachoeira, e mesmo em máquinas fracas hoje em dia haverá mais memória do que um PlayStation 4 ou XBox One. Além disso, quando o Windows fica sem memória, ele começa a jogar o excesso em uma troca e os consoles simplesmente encerram seu aplicativo e vão descobrir onde você errou.
As ferramentas integradas do Unity tiveram que ser eliminadas quase imediatamente: no Unity 2018.4 elas realmente não funcionavam com nosso jogo (tirar um instantâneo do estado da memória poderia levar mais de 8 horas, mas no PlayStation eu nunca consegui esperar por isso em princípio). Ele ficou muito melhor em 2019.x, mas não pudemos mudar para ele - alterar a versão principal do motor no Unity quebra muito.
PlayStation 4 Memory Analyzer. , , ( ). alloc/realloc/free , , memory pool' ..
. , Mono, , , BoehmGC. , , , - , . , .
Unity
, . Owlcat Games , , C++, - , , , , , . , - , , GC - .
, ? … ( , BoehmGC PS4). , - , . - , , gc_malloc__. . C++ - "". "", , . , , , . , --- ( - ) ", , , , ", . , - , , - , - .
BoehmGC : -, ( ) , -, , " ". BoehmGC, , , , , - , , , X, , , . , , , BoehmGC - PlayStation , ( BoehmGC, Mono).
.
, , . - , , , C++. : , il2cpp, , , , , - , … , , - , Unity , , PC, il2cpp .
, , Mono? , . Mono, Unity, . , , , , , , , - (, Mono Unity - , , PlayStation!).
!
, , Heap-Prof, Mono, , , . , , :
, , " ".
( " ") , . , - " ".
, heap-prof dll, , GetProcAddress Mono, , … . mono_object_is_alive. , , , Mono, Massimiliano Mantione, Mono-dev 2009 . , heap-prof, , "The problem is that this is not reliable: "mono_object_is_alive" was not meant to be a public function. And in fact sometimes the heap snapshots are wrong (or the profiler crashes).". , API , SGen, Unity Mono …
( ) , : , mono_object_is_alive . - , , ?! , ( ).
, , , , . , . - - , - ? ? "" - , . , - (, , A B, A B, A - , B, ). , , .
BoehmGC, , - , , - . Mono , , . - … , .
" ! …"
. , , "- " . , , - , , . , .
, , , , , , , ( Unity).
, , , , . , , , , .
, , ( , ). PDB Unity Player: , , , , , , ( , ). , Unity , Microsoft Detours .
. , 20 , 5-10 ( ). , , , , : ~2 ~200Mb . /UI, , , , /UI ( ).
( ) .
, Qt5, ( , , , -, Microsoft). , SQLite ( ) , memory mapped database . Unity, , , ( , ), , , managed - .
. , - . , , , . ( -!) . , Unity, Owlcat Grooming Toolkit. CPU , dotTrace, .