Под iOS, когда я использую свое приложение интенсивно Я всегда получаю через несколько минут предупреждения о низкой памяти, следующие краху моего приложения. Поэтому я сделал это простое испытание:IOS + delphi: предупреждения о низкой памяти - возможная утечка памяти с TTexture?
var MyTexture : Texture;
while true do begin
MyTexture := buildTexture(aStream);
MyTexture.free;
MyTexture := nil;
end;
Обычно это должно выполняться без каких-либо проблем. Однако через одну или две минуты я получаю предупреждения с низкой памятью и вскоре после закрытия моего приложения.
Почему у меня есть память Утечка здесь?
UPDATE/NOTE
Я работаю весь день, чтобы изолировать именно там, где проблема, и дал полный рабочий пример. проблема была не в ttexture, а в использовании UIIMAGE. поэтому я воспроизвести ниже рабочего примера (вам просто нужно добавить в проект любой JPG ресурс, который вы хотите, и назвал его «тест»)
uses iOSapi.UIKit,
iOSapi.Foundation;
Procedure CreateAndFreeUIImage(const aStream: TCustomMemoryStream);
var aImage: UIimage;
aData: NSData;
begin
aData :=
TNSData.Wrap(TNSData.alloc.initWithBytesNoCopy(
aStream.Memory, // bytes: A buffer containing data for the new object.
// If flag is YES, bytes must point to a memory block
// allocated with malloc.
aStream.Size, // length: The number of bytes to hold from bytes.
// This value must not exceed the length of bytes.
False)); // flag: If YES, the returned object takes ownership of the
// bytes pointer and frees it on deallocation.
try
if aData.length > 0 then begin
aImage :=
TUIImage.Wrap(TUIImage.alloc.initWithData(aData));
// Return Value: An initialized UIImage object,
// or nil if the method could not initialize the image from the specified data.
if aImage <> nil then begin
try
// this to force the creation of the image
TpointF.Create(aImage.size.Width, aImage.size.Height);
finally
aImage.release;
aImage := nil;
end;
end
end;
finally
aData.release;
aData := nil;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var aStream: TResourceStream;
begin
aStream := TResourceStream.Create(HInstance, 'test', RT_RCDATA);
button1.Tag := button1.Tag + 1;
button1.Text := 'running ('+inttostr(button1.Tag) + ' thread(s))';
TThread.CreateAnonymousThread(
procedure
begin
while true do begin
CreateAndFreeUIImage(aStream);
// sleep(100); // << if you uncomment this then it's work !
end;
end).Start;
end;
поэтому при нажатии на кнопку, вы будете создавать и бесплатно (в бесконечный цикл) UIImage. очень скоро после того, как вы получите в журнале один предупреждения о низкой памяти, следующие за жестким отключением приложения.
просто добавить сон (100) внутри цикла, а затем приложение никогда не сломается (по крайней мере, я не видел его врезаться)
также удалить один hypothese из https://developer.apple.com/reference/uikit/uiimage вы можете прочитать, что UIImage является многопоточной (так что ошибка не в этом)
так это шов, что память не ясно, сразу после того, как мы освобождаем объект, это приводит к памяти растет, как мы создаем больше объектов, чем выпуск памяти (это то, что я понимаю,).
Это ошибка? каково обходное решение? это их способ принудительно освободить изображение (или от мусора памяти?)
Возможно, утечка в 'buildTexture', которые мы не можем видеть. Разве у нас нет [mcve]. И зачем использовать 'Free' и задавать переменную' nil', а затем перезаписывать переменную. Вам нужно только сделать это. Поскольку вы хотите перезаписать, вы можете удалить последние две строки цикла. –
@DavidHeffernan не будет удалять ** 2 ** последние строки кода меняют способ, которым он должен себя вести? Предположительно пример OP демонстрирует mem-leak в создании/уничтожении TTexture. Разумеется, создание множества объектов без уничтожения может привести к утечке памяти. – Kromster
@Kromster No. Это мобильный компилятор с ARC. –