klepto2 Posted June 14, 2024 Posted June 14, 2024 this might be rarely usecase, but when you run this code: #include "UltraEngine.h" #include "ComponentSystem.h" //#include "Steamworks/Steamworks.h" using namespace UltraEngine; SIZE_T PrintMemoryInfo() { auto myHandle = GetCurrentProcess(); //to fill in the process' memory usage details PROCESS_MEMORY_COUNTERS pmc; //return the usage (bytes), if I may if (GetProcessMemoryInfo(myHandle, &pmc, sizeof(pmc))) return(pmc.WorkingSetSize); else return 0; } shared_ptr<Entity> main_instance; vector<shared_ptr<Entity>> instances; void UpdateHook(shared_ptr<Object> source, shared_ptr<Object> extra) { auto world = extra->As<World>(); if (world != NULL) { instances.clear(); for (int i = 0; i < 100; i++) { instances.push_back(main_instance->Instantiate(world)); } } } int main(int argc, const char* argv[]) { #ifdef STEAM_API_H if (not Steamworks::Initialize()) { RuntimeError("Steamworks failed to initialize."); return 1; } #endif RegisterComponents(); auto cl = ParseCommandLine(argc, argv); //Load FreeImage plugin (optional) auto fiplugin = LoadPlugin("Plugins/FITextureLoader"); //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); if (!AttachConsole(ATTACH_PARENT_PROCESS)) { if (AllocConsole()) { freopen("conin$", "r", stdin); freopen("conout$", "w", stdout); freopen("conout$", "w", stderr); } } else { auto consoleHandleOut = GetStdHandle(STD_OUTPUT_HANDLE); auto consoleHandleIn = GetStdHandle(STD_INPUT_HANDLE); auto consoleHandleErr = GetStdHandle(STD_ERROR_HANDLE); if (consoleHandleOut != INVALID_HANDLE_VALUE) { freopen("conout$", "w", stdout); setvbuf(stdout, NULL, _IONBF, 0); } if (consoleHandleIn != INVALID_HANDLE_VALUE) { freopen("conin$", "r", stdin); setvbuf(stdin, NULL, _IONBF, 0); } if (consoleHandleErr != INVALID_HANDLE_VALUE) { freopen("conout$", "w", stderr); setvbuf(stderr, NULL, _IONBF, 0); } } //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a world auto world = CreateWorld(); auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->Move(0, 2, -8); world->RecordStats(true); main_instance = CreatePlane(world, 10.0, 10.0, 256, 256); world->AddHook(HOOKID_UPDATE, UpdateHook, world); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer); #ifdef STEAM_API_H Steamworks::Update(); #endif window->SetText("Instances: " + String(world->renderstats.instances) + " MEM: " + String(PrintMemoryInfo() / 1024) + " kb"); } #ifdef STEAM_API_H Steamworks::Shutdown(); #endif return 0; } You can observe the following: The memory rises a lot without going down. After some seconds, normally when the memory is above 300000kb the app spams Error: Invalid value While the memory has not so much impact, the Invalid value error leads to flickering (not so much in this sample, but in the original source i use the instances gets rendered totally random) and wrong rendering of the instances. 1 Quote Windows 10 Pro 64-Bit-Version NVIDIA Geforce 1080 TI
Dreikblack Posted February 13 Posted February 13 Updated code to make it buildable on 0.9.9: #include "UltraEngine.h" #include "ComponentSystem.h" //#include "Steamworks/Steamworks.h" using namespace UltraEngine; SIZE_T PrintMemoryInfo() { auto myHandle = GetCurrentProcess(); //to fill in the process' memory usage details PROCESS_MEMORY_COUNTERS pmc; //return the usage (bytes), if I may if (GetProcessMemoryInfo(myHandle, &pmc, sizeof(pmc))) return(pmc.WorkingSetSize); else return 0; } shared_ptr<Entity> main_instance; vector<shared_ptr<Entity>> instances; void UpdateHook(shared_ptr<Object> source, shared_ptr<Object> extra) { auto world = extra->As<World>(); if (world != NULL) { instances.clear(); for (int i = 0; i < 100; i++) { instances.push_back(main_instance->Instantiate(world)); } } } int main(int argc, const char* argv[]) { RegisterComponents(); auto cl = ParseCommandLine(argc, argv); //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); if (!AttachConsole(ATTACH_PARENT_PROCESS)) { if (AllocConsole()) { freopen("conin$", "r", stdin); freopen("conout$", "w", stdout); freopen("conout$", "w", stderr); } } else { auto consoleHandleOut = GetStdHandle(STD_OUTPUT_HANDLE); auto consoleHandleIn = GetStdHandle(STD_INPUT_HANDLE); auto consoleHandleErr = GetStdHandle(STD_ERROR_HANDLE); if (consoleHandleOut != INVALID_HANDLE_VALUE) { freopen("conout$", "w", stdout); setvbuf(stdout, NULL, _IONBF, 0); } if (consoleHandleIn != INVALID_HANDLE_VALUE) { freopen("conin$", "r", stdin); setvbuf(stdin, NULL, _IONBF, 0); } if (consoleHandleErr != INVALID_HANDLE_VALUE) { freopen("conout$", "w", stderr); setvbuf(stderr, NULL, _IONBF, 0); } } //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a world auto world = CreateWorld(); auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->Move(0, 2, -8); world->RecordStats(true); main_instance = CreatePlane(world, 10.0, 10.0, 256, 256); world->AddHook(HOOKID_UPDATE, UpdateHook, world); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer); window->SetText("Instances: " + String(world->renderstats.instances) + " MEM: " + String(PrintMemoryInfo() / 1024) + " kb"); } return 0; } Having same error - "Error: Invalid value" Quote
Josh Posted March 3 Posted March 3 Okay, this is reliably producing the OpenGL value GL_INVALID_VALUE... Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Josh Posted March 3 Posted March 3 Okay, the invalid value error was a simple fix, just some wrong buffer sizing code... Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Josh Posted March 3 Posted March 3 Here is a simpler example that shows a mem leak when the space key is pressed. I will start with this. #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { auto cl = ParseCommandLine(argc, argv); //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a world auto world = CreateWorld(); auto camera = CreateCamera(world); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if (window->KeyDown(KEY_SPACE)) CreatePivot(world); world->Update(); world->Render(framebuffer); window->SetText("MEM: " + String(GetMemoryUsage(true) / 1024) + " kb"); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Josh Posted March 3 Posted March 3 Even simpler: #include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); auto framebuffer = CreateFramebuffer(window); auto world = CreateWorld(); auto camera = CreateCamera(world); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if (window->KeyDown(KEY_SPACE)) CreatePivot(NULL); world->Update(); world->Render(framebuffer); auto mem = GetMemoryUsage(true); window->SetText("MEM: " + String(mem) + " kb"); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Josh Posted March 3 Posted March 3 Even simpler. Looks like a memory leak simply by creating anything based off the Entity class... #include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if (window->KeyDown(KEY_SPACE)) { std::make_shared<Pivot>(); } Sleep(16); auto mem = GetMemoryUsage(true); window->SetText("MEM: " + String(mem) + " kb"); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Josh Posted March 3 Posted March 3 Ah okay, in my previous test KEY_REPEAT events were piling up, causing a leak. This example has no memleak: #include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if (window->KeyDown(KEY_SPACE)) { std::make_shared<Pivot>(); } Sleep(16); while (PeekEvent()) WaitEvent(); auto mem = GetMemoryUsage(true); window->SetText("MEM: " + String(mem) + " kb"); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Josh Posted March 3 Posted March 3 No problems with this example: #include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); auto framebuffer = CreateFramebuffer(window); auto world = CreateWorld(); auto cam = CreateCamera(world); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if (window->KeyDown(KEY_SPACE)) { CreatePivot(NULL); } while (PeekEvent()) WaitEvent(); world->Update(); world->Render(framebuffer); auto mem = GetMemoryUsage(true); window->SetText("MEM: " + String(mem) + " kb"); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Josh Posted March 3 Posted March 3 Okay, this is the point where the memleak resumes. #include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); auto framebuffer = CreateFramebuffer(window); auto world = CreateWorld(); auto cam = CreateCamera(world); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if (window->KeyDown(KEY_SPACE)) { CreatePivot(world); } while (PeekEvent()) WaitEvent(); world->Update(); world->Render(framebuffer); auto mem = GetMemoryUsage(true); window->SetText("MEM: " + String(mem) + " kb"); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Josh Posted March 4 Posted March 4 I found several errors, and this example now runs with stable memory usage: #include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); auto framebuffer = CreateFramebuffer(window); auto world = CreateWorld(); auto cam = CreateCamera(world); while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if (window->KeyHit(KEY_SPACE)) { CreateBox(world); } while (PeekEvent()) WaitEvent(); world->Update(); world->Render(framebuffer); world->GetEntities(); auto mem = GetMemoryUsage(true); window->SetText("MEM: " + String(mem / 1024) + " kb"); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Josh Posted March 4 Posted March 4 This example is now stable, but if you change CreatePivot to CreateModel, it is not stable... #include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char* argv[]) { //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a world auto world = CreateWorld(); world->RecordStats(true); auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->Move(0, 2, -8); auto main_instance = CreatePivot(world);// Plane(world, 10.0, 10.0, 256, 256); vector<shared_ptr<Entity>> instances; while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { instances.clear(); for (int n = 0; n < 100; ++n) { instances.push_back(main_instance->Instantiate(world)); } world->Update(); world->Render(framebuffer); while (PeekEvent()) WaitEvent(); window->SetText("Instances: " + String(world->renderstats.instances) + " MEM: " + String(GetMemoryUsage(true) / 1024) + " kb"); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Solution Josh Posted March 4 Solution Posted March 4 Okay, this slight modification of your code will produce steady mem usage in the next build. Changes Removed the call to LoadPlugin() Added a line that clears events out. I am compiling the update now and I will upload it tomorrow morning (California time). #include "UltraEngine.h" #include "ComponentSystem.h" //#include "Steamworks/Steamworks.h" using namespace UltraEngine; SIZE_T PrintMemoryInfo() { auto myHandle = GetCurrentProcess(); //to fill in the process' memory usage details PROCESS_MEMORY_COUNTERS pmc; //return the usage (bytes), if I may if (GetProcessMemoryInfo(myHandle, &pmc, sizeof(pmc))) return(pmc.WorkingSetSize); else return 0; } shared_ptr<Entity> main_instance; vector<shared_ptr<Entity>> instances; void UpdateHook(shared_ptr<Object> source, shared_ptr<Object> extra) { auto world = extra->As<World>(); if (world != NULL) { instances.clear(); for (int i = 0; i < 100; i++) { instances.push_back(main_instance->Instantiate(world)); } } } int main(int argc, const char* argv[]) { #ifdef STEAM_API_H if (not Steamworks::Initialize()) { RuntimeError("Steamworks failed to initialize."); return 1; } #endif RegisterComponents(); auto cl = ParseCommandLine(argc, argv); //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); if (!AttachConsole(ATTACH_PARENT_PROCESS)) { if (AllocConsole()) { freopen("conin$", "r", stdin); freopen("conout$", "w", stdout); freopen("conout$", "w", stderr); } } else { auto consoleHandleOut = GetStdHandle(STD_OUTPUT_HANDLE); auto consoleHandleIn = GetStdHandle(STD_INPUT_HANDLE); auto consoleHandleErr = GetStdHandle(STD_ERROR_HANDLE); if (consoleHandleOut != INVALID_HANDLE_VALUE) { freopen("conout$", "w", stdout); setvbuf(stdout, NULL, _IONBF, 0); } if (consoleHandleIn != INVALID_HANDLE_VALUE) { freopen("conin$", "r", stdin); setvbuf(stdin, NULL, _IONBF, 0); } if (consoleHandleErr != INVALID_HANDLE_VALUE) { freopen("conout$", "w", stderr); setvbuf(stderr, NULL, _IONBF, 0); } } //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a world auto world = CreateWorld(); auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetFov(70); camera->Move(0, 2, -8); world->RecordStats(true); main_instance = CreatePlane(world, 10.0, 10.0, 256, 256); world->AddHook(HOOKID_UPDATE, UpdateHook, world); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer); #ifdef STEAM_API_H Steamworks::Update(); #endif window->SetText("Instances: " + String(world->renderstats.instances) + " MEM: " + String(PrintMemoryInfo() / 1024) + " kb"); } while (PeekEvent()) WaitEvent(); #ifdef STEAM_API_H Steamworks::Shutdown(); #endif return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.