Why is GC kicking in to delete a valid, oft-used pointer ?

Based on this post, I built my own function to load a texture from disk.

(Why this instead of a reference to the content browser? I have my reasons. :wink: )

UTexture2D* AMyHUD::LoadTexture(FString TextureFilename)
	TArray<uint8> RawFileData;
	UTexture2D *mytex = NULL;

	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	// Note: PNG format.  Other formats are supported
	IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);

	if (FFileHelper::LoadFileToArray(RawFileData, *TextureFilename))
		if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()))
			const TArray<uint8>* UncompressedBGRA = NULL;
			if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA))
				mytex = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_B8G8R8A8);

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

			// Update the rendering resource from data.

	return mytex;

This is only used to show a texture on an AHUD actor like so:

void AMyHUD::DrawHUD()
    DrawTexture(MyTexturePtr, 0, 0,Dim.X, Dim.Y, 0, 0, 1, 1);

So nothing is deliberately destroyed during the process that would cause a side-effect to the life-cycle of the texture, everything works fine up to a few seconds (5 to 20) until the garbage collector kicks in and calls Texture2D::BeginDestroy(). And I can’t understand why. The pointer is constantly used for display so I can’t see why the GC decides it’s time to give it up.

Maybe the creation method UTexture2D::CreateTransient() isn’t adequate and puts a “timer” of sorts in the life cycle of this object.

Any help appreciated.

Have you decorated MyTexturePtr properly with a UPROPERTY()? I.e. declared as follows in your .h file?:

UTexture2D* MyTexturePtr;

The garbage collector needs this otherwise it doesn’t care whether there are any references to it (as far as I know).

That seems to do the trick. And a good lesson to revise much of my code accordingly. Thank you very much.

Yup. The first time this happened to me it took two full days of debugging and reading to figure it out. Not forgetting that lesson soon.