Memory increasing with time

  • 402 Views
  • Last Post 6 days ago
Leif posted this 22 November 2016

I am testing our code for memory leaks, and I've found that the memory used continually increases with time which is unacceptable. I am assuming this is an issue with our code. Anyway, I created a bare bones test, which repeatedly loads and unloads the engine. Then I used the Visual Studio Performance and Diagnostics tools to analyses memory after each loop. I find that memory usage increases with time.

Here is the test code (with the licence key removed) which repeatedly loads and unloads the ABBYY engine:

void Test_3() { while (true) { std::cout << "Press x then Enter to exit, or Enter to continue ..."; int cval = getc(stdin); if (cval == 'x') { break; }

    CoInitialize(NULL);
    CLSID clsid = __uuidof(FREngine::InprocLoader);
    UUID iid = __uuidof(FREngine::IEngineLoader);
    FREngine::IEngineLoaderPtr engineLoaderPtr;
    HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, (void**)&engineLoaderPtr);
    if (hr != S_OK)
    {
        if (hr == REGDB_E_CLASSNOTREG)
        {
            std::cout << "REGDB_E_CLASSNOTREG" << std::endl;
        }
        else
        {
            std::cout << "Error: unable to create the engine" << std::endl;
        }
        return;
    }

    try
    {
        FREngine::IEnginePtr engine = engineLoaderPtr->GetEngineObject(L"[the licence key]");

        engineLoaderPtr->ExplicitlyUnload();
        engine = nullptr;
        engineLoaderPtr = nullptr;

        CoUninitialize();
    }
    catch (_com_error&)
    {
        std::cout << "Error: unable to load the ABBYY FineReader COM object" << std::endl;
        return;
    }
    catch (...)
    {
        // No special processing needed
        std::cout << "Error: unknown reason" << std::endl;
    }
}

}

I get much bigger increases in memory usage with more complex scenarios - loading images and extracting test - but the above is nice and easy to describre.

Order By: Standard | Newest | Votes
Anna Fedyushkina posted this 23 November 2016

Please try to swap 2 rows in your code so that the engine gets destructed before deinitialization. You can apply this code sample:

engine = nullptr; engineLoaderPtr->ExplicitlyUnload(); engineLoaderPtr = nullptr;

Please let us know about the results.

Leif posted this 24 November 2016

Thank you Anna.

To test your suggestion I repeatedly loaded and unloaded the engine, and recorded memory use every 50 iterations. The results are as follows:

Iteration   Memory change    Memory
0           0                124KB
50          +457KB           581KB
100         +24KB            606KB
140         -77KB            528KB
200         +72KB            600KB
250         +2.7MB           3.29MB
300         +1.69MB          4.97MB
350         -443KB           4.54MB
400         -2.37MB          2.17MB
450         +11KB            2.18MB

So the net result is a large increase in memory usage. This is for us not an issue since we only load and unload once per session. But I also see large memory increases when we load and process images. I'll write a simple example unit test.

Leif posted this 24 November 2016

Thank you again for your help. I've located the cause of the large memory increases that we see when loading an image into a document, and closing the document, and the issue is in our code. Basically I made an error when marshalling interfaces between threads, which meant COM interfaces were not being released. I have further testing to do, but in the meantime apologies for troubling you.

Anna Fedyushkina posted this 25 November 2016

Happy to know that you have solved the issue! :)

Gustavo Carpaneses posted this 4 weeks ago

Dear Leif,

 

could you share the solution that you applied? I´m experiencing the same problem.

 

Actually I call the Close method of the FRDocument object and then set null to it.

 

Tks.

Anna Fedyushkina posted this 6 days ago

Gustavo,

Please send the following information to SDK_Support@abbyy.com so that we could help you:

  • Serial number of your license.
  • An Engine log, generated by your program. Such log can be obtained by calling StartLogging() method of the Engine object after it is initialized.
  • A minimal project that reproduces your issue and instructions of how to launch such project.

Leif posted this 6 days ago

Dear Leif,

could you share the solution that you applied? I´m experiencing the same problem.

Actually I call the Close method of the FRDocument object and then set null to it.

Tks.

Hello Gustavo

It sounds like ABBYY will solve your problem. However FYI here is the COM marshalling code:

https://www.codeproject.com/Articles/1155484/Cplusplus-Template-Classes-to-Make-COM-Marshalling

It makes life a lot easier. .

Close