Показать сообщение отдельно
Старый 02.11.2016, 22:43
Nooob вне форума Посмотреть профиль Отправить личное сообщение для Nooob Найти все сообщения от Nooob
  № 8  
Ответить с цитированием
Nooob
 
Аватар для Nooob

Регистрация: Mar 2007
Сообщений: 319
Да все там понятно как работает, как и везде
https://github.com/nxmirrors/tamarin...Utils.cpp#L223
https://github.com/nxmirrors/tamarin...Utils.cpp#L132

И мерить память в момент запуска не следует
Код AS3:
	public class DisposeTest extends Sprite
	{
		public function DisposeTest()
		{
			super();
			stage.addEventListener(MouseEvent.CLICK, onClick);
		}
 
		private function onClick(event:MouseEvent):void
		{
			var memory:int = System.privateMemory;
			var bd:BitmapDataExtended = new BitmapDataExtended(2000,2000,true,0x0);
			trace((-memory + (memory = System.privateMemory))); //16003072
			bd.dispose();
			bd = null;
			System.gc();
			trace((-memory + (memory = System.privateMemory))); //-16003072
			trace("----");
		}
	}
В конструкторе приложения нельзя мерить память, так как эта та точка вызова as кода когда еще окно не создалось, контекст рендера не инициализировался, возможно даже буфер на trace не выделился, и значения в первом случае с BitmapData тоже будут с долей вероятности разные, попробуй первый вариант запускать раз 20 подряд

Ответ на вопрос что собственно показывает System.privateMemory https://github.com/nxmirrors/tamarin...Class.cpp#L215 https://github.com/nxmirrors/tamarin...rtWin.cpp#L188
На почитать http://msdn.microsoft.com/en-us/library/bb331824.aspx https://habrahabr.ru/post/202242/

По поводу памяти занимаемой изображением
Если у тебя приложение работает с загружаемыми картинками, то нужно понимать что в памяти хранятся не пиксели (как принято думать), а пиксели + сжатое изображение + выделяется память в момент разжатия
Например тест:
Код AS3:
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function (event:Event):void
			{
				var bitmap:Bitmap = Bitmap(loader.contentLoaderInfo.content);
				trace("Предполагаемая занимаемая память:", bitmap.bitmapData.width * bitmap.bitmapData.height * 4); //5615780
				var memory:int = System.privateMemory;
				var color:uint = bitmap.bitmapData.getPixel32(0, 0);
				trace("Выделенная память после чтения:", (-memory + (memory = System.privateMemory))); //11239424
				bitmap.bitmapData.dispose();
				trace("Освободившаяся память после уничтожения:", (memory - (memory = System.privateMemory))); //5619712
			});
			loader.load(new URLRequest("http://www.freeiconspng.com/uploads/superman-logo-png-4.jpeg"));
Нужно помнить, что как только ты попытаешься считать/отрисовать/поместить на экран данные из bitmapData изображение будет разжато в пиксели и будет выделено больше памяти для декодера (примерно в два раза больше чем само изображение), и соответственно память освободится если перестанешь читать после вызова сборки. Флеш это делает для экономии памяти в случае если изображение уже не используется, но может быть использовано так как ссылка на него осталась.

Догадливый человек скажет, что есть же ImageDecodingPolicy
Код AS3:
var context:LoaderContext = new LoaderContext();
context.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD;
Но после первого цикла чтения и отработки сборки, поведение будет таким же как и при ON_DEMAND

Если хочешь избавиться от этого эффекта, то нужно загруженную bitmapData скопировать попиксельно (не клонировать), а loader'у сделать unload. Тогда у тебя будет бОльший контроль над выделяемой памятью и поведение будет более предсказуемым.
Код AS3:
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function (event:Event):void
			{
				var bitmapData:BitmapData = Bitmap(loader.contentLoaderInfo.content).bitmapData;
				var newBitmapData:BitmapData = new BitmapData(bitmapData.width, bitmapData.height, bitmapData.transparent, 0x0);
				for (var x:int = 0; x < bitmapData.width; x++) 
				{
					for (var y:int = 0; y < bitmapData.width; y++) 
					{
						if (bitmapData.transparent)
						{
							newBitmapData.setPixel32(x, y, bitmapData.getPixel32(x, y));
						}
						else
						{
							newBitmapData.setPixel(x, y, bitmapData.getPixel(x, y));
						}
					}
				}
				bitmapData.dispose();
				loader.unloadAndStop(true);
 
				//Далее использовать только newBitmapData
			});
			loader.load(new URLRequest("http://www.freeiconspng.com/uploads/superman-logo-png-4.jpeg"));


Последний раз редактировалось Nooob; 03.11.2016 в 04:04.