• 我不去想是否能够成功
    既然选择了远方 便只顾风雨兼程

    我不去想能否赢得爱情
    既然钟情于玫瑰 就勇敢地吐露真诚

    我不去想身后会不会袭来寒风冷雨
    既然目标是地平线 留给世界的只能是背影

  • 我有一个梦想,只是有一个梦想。

  • 首页
  • 文章列表
  • [UE4]追查了两天内存疯狂泄露的原因,竟然是Log没关???——UE4如何查内存泄露
虽然你学的慢,但是你,放弃的快呀。

[UE4]追查了两天内存疯狂泄露的原因,竟然是Log没关???——UE4如何查内存泄露

各种怀疑,各种debug,最后发现是log窗口没关,因为cache机制所以内存越来越多。然后内存耗尽。。。
好吧,我比较菜。
一天后。。。[更新]
内存耗尽和log窗口的log关系不大(为了减少LOG的影响,可以在项目里面把UE_LOG定义为空,这样就不会被log影响日志了。),主要是ue4下使用std标准库,因为不同的内存管理机制,会造成内存被cache住无法释放。

在UE4引擎端,会hook所有的内存分配。
`Engine\Source\Runtime\Core\Public\HAL\FMemory.inl`
```c++
FMEMORY_INLINE_FUNCTION_DECORATOR void* FMemory::Malloc(SIZE_T Count, uint32 Alignment)
{
	void* Ptr;
	if (!FMEMORY_INLINE_GMalloc)
	{
		Ptr = MallocExternal(Count, Alignment);
	}
	else
	{
		DoGamethreadHook(0);
		FScopedMallocTimer Timer(0);
		Ptr = FMEMORY_INLINE_GMalloc->Malloc(Count, Alignment);
	}
	// optional tracking of every allocation
	LLM_IF_ENABLED(FLowLevelMemTracker::Get().OnLowLevelAlloc(ELLMTracker::Default, Ptr, Count, ELLMTag::Untagged, ELLMAllocType::FMalloc));
	return Ptr;
}

FMEMORY_INLINE_FUNCTION_DECORATOR void* FMemory::Realloc(void* Original, SIZE_T Count, uint32 Alignment)
{
	// optional tracking -- a realloc with an Original pointer of null is equivalent
	// to malloc() so there's nothing to free
	LLM_REALLOC_SCOPE(Original);
	LLM_IF_ENABLED(if (Original != nullptr) FLowLevelMemTracker::Get().OnLowLevelFree(ELLMTracker::Default, Original, ELLMAllocType::FMalloc));

	void* Ptr;
	if (!FMEMORY_INLINE_GMalloc)
	{
		Ptr = ReallocExternal(Original, Count, Alignment);
	}
	else
	{
		DoGamethreadHook(1);
		FScopedMallocTimer Timer(1);
		Ptr = FMEMORY_INLINE_GMalloc->Realloc(Original, Count, Alignment);
	}

	// optional tracking of every allocation - a realloc with a Count of zero is equivalent to a call 
	// to free() and will return a null pointer which does not require tracking. If realloc returns null
	// for some other reason (like failure to allocate) there's also no reason to track it
	LLM_IF_ENABLED(if (Ptr != nullptr) FLowLevelMemTracker::Get().OnLowLevelAlloc(ELLMTracker::Default, Ptr, Count, ELLMTag::Untagged, ELLMAllocType::FMalloc));

	return Ptr;
}

FMEMORY_INLINE_FUNCTION_DECORATOR void FMemory::Free(void* Original)
{
	if (!Original)
	{
		FScopedMallocTimer Timer(3);
		return;
	}

	// optional tracking of every allocation
	LLM_IF_ENABLED(FLowLevelMemTracker::Get().OnLowLevelFree(ELLMTracker::Default, Original, ELLMAllocType::FMalloc));

	if (!FMEMORY_INLINE_GMalloc)
	{
		FreeExternal(Original);
		return;
	}
	DoGamethreadHook(2);
	FScopedMallocTimer Timer(2);
	FMEMORY_INLINE_GMalloc->Free(Original);
}

```
所有的内存分配如果是新增内存,走 FMemory::Malloc,如果是已有内存走 FMemory::Realloc。std有自己的一套内存管理机制。会造成内存无法被ue4立即释放。
所以最后是用TArray,TMap,TSet等Ue4容器代替std容器。
然后在FMomory::Malloc和Memory::Realloc设置断点,追查所有的新开内存,然后逐个优化掉,即可。
标签ue4

最新评论