Przede wszystkim musisz zrozumieć, że to co robisz jest dość dziwne!
„normalna” sposób, aby załadować tekstury jest użycie rurociągu treści i Content Manager.
Jeśli naprawdę trzeba załadować teksturę z pliku, a nie systemu treści - należy to zrobić tylko raz dla każdej fakturze. Należy użyć Texture2D.FromFile
w Game.LoadContent
, i nazywają Dispose
w Game.UnloadContent
(zwykle Content Manager będzie obsługiwać wywołanie Dispose dla ciebie - ale dlatego, że nie zamierzamy poprzez Content Manager trzeba zadzwonić utylizować siebie).
Ważną rzeczą jest, aby uświadomić sobie, że pracujesz z obu zarządzane i niezarządzani zasobów tutaj.
Pamięć używana przez zarządzane obiekty będzie obsługiwana przez garbage collector - w tym przypadku każde wystąpienie Texture2D używa małego fragmentu zarządzanej pamięci z niewielkim. 99% czasu, o którym nie musisz się martwić - śmieciarz jest naprawdę dobry w zarządzaniu pamięcią zarządzaną - to jest jego zadanie!
Musisz się martwić o niezarządzane zasoby - w tym przypadku pamięć tekstur używana przez wszystkie te tekstury, które ładujesz. Ostatecznie garbage collector będzie działać, zobaczyć te wszystkie obiekty bez odniesień Texture2D i je odebrać. Gdy je zbierze, sfinalizuje je, co, podobnie jak wywołanie Dispose, uwolni zasoby niezarządzane.
Ale garbage collector nie „widzi” wszystkie niezarządzanych zasoby te Texture2D przedmioty są używane. Nie wie kiedy te obiekty muszą zostać zwolnione - sam możesz zrobić o wiele lepszą pracę. Wszystko, co musisz zrobić, to zadzwonić pod numer Dispose
w teksturach, gdy nie są już potrzebne.
To dlatego, że śmieciarz nie wie o tym 30 MB dodatkowej pamięci używanej przez tekstury, że jest on gromadzony, gdy nie dzwonisz do dyspozycji. Oprócz tego, czego nie widać, gdy patrzymy na wykorzystanie pamięci procesowej, to cała pamięć GPU, której używają te tekstury!
(Podstawową implementacją Texture2D jest to, że zawiera odniesienie do obiektu tekstury DirectX - który sam jest obiektem niezarządzanym przy użyciu niezarządzanej pamięci głównej - który z kolei obsługuje teksturę i związaną z nią pamięć na GPU. od obiektu Texture2D jest tylko około 100-200 bajtów. - która przechowuje wspomnianą odniesienia i cache szerokość, wysokość, formatu tekstury i tak dalej)
teraz - jak na to, co staramy się osiągnąć . Jeśli naprawdę mają potrzebę, aby załadować tekstury każdej ramki (to wysoce nietypowe), a następnie także nie trzeba już poprzednią tekstury ...
Cóż, przede wszystkim, nazywając Dispose
na niewykorzystane tekstury każda ramka jest prawidłowy sposób. Będziesz zależał od śmieciarza, aby wyczyścić wszystkie śmieci, które tworzy (zarządzana strona obiektów Texture2D) - jest to dobre w Windowsie, ale może zabić twoją wydajność na Xboksie. Przynajmniej nie będziesz przeciekać niezarządzanych zasobów.
Lepszą metodą, szczególnie jeśli tekstura ma taki sam rozmiar za każdym razem, jest po prostu używanie tego samego obiektu tekstury. Następnie wywołaj na nim Texture2D.SetData
z nowymi danymi tekstury każdej klatki.
(jeżeli tekstury są różne rozmiary, albo masz więcej niż jeden używany w danym czasie, może trzeba zaimplementować coś takiego basenu tekstur.)
Oczywiście loadFile bierze rzeczywisty plik SetData pobiera nieprzetworzone dane. Konieczne będzie samodzielne wdrożenie konwersji danych. Dobrym punktem wyjścia może być this thread on the XNA forum.