Download

TArray MemLeak problem

Hi.

I’m probably doing something wrong, but I’m running out of ideas what is going on:
I’m downloading images via HTTP Request and making an UTexture2D from then and then I store them in the TArray:



UTexture2D* NewImg = UTexture2D::CreateTransient(256, 256, PF_B8G8R8A8);

void* TextureData = NewImg->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(TextureData, UncompressedRGBA->GetData(), UncompressedRGBA->Num());
NewImg->PlatformData->Mips[0].BulkData.Unlock();
NewImg->UpdateResource();

Images.Add(NewImg);


The Images is a TArray<UTexture2D*> with UPROPERTY()

Everything works fine, but I have a problem with deleting those images. I thought this should do a trick:



for (auto Img(Images.CreateIterator()); Img; ++Img)
{
	if ((*Img)->IsValidLowLevel() == true)
	{
		(*Img)->ConditionalBeginDestroy();
		*Img = nullptr;
	}
}
Images.Empty();
GameInstance->GetWorld()->ForceGarbageCollection(true);


The “Texture Memory Used” from “Stat Memory” is freed, but the “Used Virtual” and “Used Physical” don’t.
When I’m getting and removing those textures sooner or later I can get a crash by losing memory.
Is there something I should do except ConditionalBeginDestroy, calling GC and clearing the array?
Help!

You should never manually do most of those things!

IsValidLowLevel should not be necessary. I know it has been popularized in some of the wiki examples written by community members, but seriously, it should never be necessary in regular code.

BeginDestroy is part of the garbage collection process and used for cleaning up resources held by an object after it has been tagged for garbage collection. You should never call it manually.

In your case, simply calling Empty on the array should cause the textures to be garbage collection the next time it runs. If you really need it to happen immediately, then doing the Empty and then ForceGC should also do it.

If you are concerned that there are references to the textures from other locations that are keeping it from being garbage collected and you definitely want to force it, you could call MarkPendingKill on each object in the array before emptying it which will force garbage collection to clean it up and null out references regardless of whether there are other references to the textures.

Hi Marc Audy, with your comment i notice some bad things on my code!, and always notice almost all have some dad code methodology or implementation, indeed!, get the UE source code is very cool!!!, but i always solve my projects reading the stuff for a while, but always feel i am doing something wrong, the wiki page is great but i think have some lacks, may i suggest create some tutorials from c++ relatives on good use of the most important topics! what prevent, what use, what avoid. also check for game basics, like social media integration easy, the general stuff i mean

Cheers!

Can you markup articles with bad implementation in order to beginners don’t use it?

Unfortunately that isn’t very easily done. We do get quite a few new articles and updates every day, but we do not go through all of them to test for accuracy. Some articles are also correct when first written, but then later the workflow changes or properties are renamed, so it’s not something we are able to track like our documentation. Instead we have a system for wiki users to rank tutorial pages using a 5-star rating system. If a wiki page is bad, you can vote on it or edit it yourself to include a note that something is broken.

The wiki is free for the community to edit except a few technical pages, so feel free to go to the page and make some changes. You can also start posting in the discussion page of a bad wiki page to get the author’s attention.

Thanks Marc Audy that helped a lot!
I was looking at this How to safely delete UObject instantly - UE4 AnswerHub Sadly there are no strict course how to C++ in UE4 the dev-team way.

In fact we are doing some code inside the engine itself, I wasn’t sure if garbage collector works in normal classes without UCLASS() but MarkPendingKill was the thing I was looking for.

But still, the “Used Virtual” and “Used Physical” is not decreasing, but when I’m creating new textures to the new array it isn’t increasing! It looks like the memory is allocated and it’s quite confusing, because it looks like a memory leak at the first sight.
Anyway, it looks fine for now. Thanks once more time :slight_smile: