Jump to content

Memleak and Invalid Value error with Instanciate


Go to solution Solved by Josh,

Recommended Posts

Posted

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:

  1. The memory rises a lot without going down.
  2. 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.

 

  • Upvote 1
  • Windows 10 Pro 64-Bit-Version
  • NVIDIA Geforce 1080 TI
  • 7 months later...
Posted

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"

Check out Slipgate Tactics demo, which is made with Ultra Engine/Leadwerks 5:

https://www.leadwerks.com/community/topic/61480-slipgate-tactics-demo/

  • 3 weeks later...
Posted

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;
}

 

Let's build cool stuff and have fun. :)

Posted

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;
}

 

Let's build cool stuff and have fun. :)

Posted

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;
}

 

Let's build cool stuff and have fun. :)

Posted

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;
}

 

Let's build cool stuff and have fun. :)

Posted

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;
}

 

Let's build cool stuff and have fun. :)

Posted

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;
}

 

Let's build cool stuff and have fun. :)

Posted

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;
}

 

Let's build cool stuff and have fun. :)

Posted

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;
}

 

Let's build cool stuff and have fun. :)

  • Solution
Posted

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;
}

 

Let's build cool stuff and have fun. :)

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...