accumulation of handles

PDF-XChange Editor SDK for Developers

Moderators: TrackerSupp-Daniel, Tracker Support, Paul - Tracker Supp, Vasyl-Tracker Dev Team, Chris - Tracker Supp, Sean - Tracker, Ivan - Tracker Software, Tracker Supp-Stefan

Forum rules
DO NOT post your license/serial key, or your activation code - these forums, and all posts within, are public and we will be forced to immediately deactivate your license.

When experiencing some errors, use the IAUX_Inst::FormatHRESULT method to see their description and include it in your post along with the error code.
Post Reply
AteBe
User
Posts: 63
Joined: Thu Dec 06, 2018 7:02 am

accumulation of handles

Post by AteBe »

Hello,
I have the following problem.
Before I open a new document, I close the previously opened document.
Nevertheless, there are no handles released.
This adds up the open handles.
After about 1500 opened documents, the application hangs and crashes.
A restart of the PDFXChangeEditor within the application does not help.
Only the termination of the complete application (the whole process) releases the handles.
How can I release the handles of the closed document?
AteBe
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: accumulation of handles

Post by Sasha - Tracker Dev Team »

Hello AteBe,

If you are using .Net then it's a common problem - their garbage collector does not release handles. What you can try is to use the

Code: Select all

GC.Collect();
GC.WaitForPendingFinalizers();
before and after document close.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
AteBe
User
Posts: 63
Joined: Thu Dec 06, 2018 7:02 am

Re: accumulation of handles

Post by AteBe »

Hallo Alex,
we are using Java and Eclipse RCP.
Does the problem you are speaking about also exist in java?
If so, how do I solve it?
If not, what else can be the reason for this Problem and how do I solve it?
AteBe
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: accumulation of handles

Post by Sasha - Tracker Dev Team »

Hello AteBe,

As the Java has it's garbage collector - it can result in the same behavior. Here's the topic that should help:
https://stackoverflow.com/questions/508 ... collection


Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
AteBe
User
Posts: 63
Joined: Thu Dec 06, 2018 7:02 am

Re: accumulation of handles

Post by AteBe »

Hallo Alex,

unfortunately, the garbage collector does not work.
Also, according to the link (https://stackoverflow.com/questions/508 ... collection) you have sent me, the garbage collector should not be used anyway.
I assume that the handles that are no longer needed are not released by the API and therefore can not be released by the garbage collector.

For all my tests, I proceeded as follows:
1. I set the "Single document mode" setting in the editor.
2. I opened document1
3. Then I opened document2

I noticed the following effects:

Standalone Editor:
- After opening (with the Open dialog or a double click in the Explorer) of document2 the handles of dokument1 are released.

Application:
- After opening (with the Open dialog) document2 wiht my settings the handles of document1 will NOT be released.
- If I import the settings from the standalone application and then open document2 with the Open dialog, the handles of document1 are released.
- When I open document2 with the API function OpenDocFromPath(), the handles of document1 are NOT released.

What are the differences between the Open dialog and the API-Funktione OpenDocFromPath()?
Are other settings used when opening a document with the Open dialog than with the OpenDocFromPath() function, that can cause this problem and if so, which ones?

AteBe
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: accumulation of handles

Post by Sasha - Tracker Dev Team »

Hello AteBe,

For starters, you have to use the Close() method for the document after you have done working with it. This will mask the problem that you have but not solve it completely (the virtual memory will be eaten anyways).

Let's talk about the Java or .Net languages from the perspective of using the COM controls. When you create a IPXC_Document typed variable, and then fill it by some method for example OpenDocument() then the Garbage Collector (GC) stores a ref to it and holds it. After you get out of the method's closure, the GC marks that that pointer should be released but the time to release it is purely defined by the GC itself. That's the base of the problem and that's why .Net and Java programs can drastically eat memory and don't release it till some time. And that's why the C++ was chosen as the language to write all of our products, because we are managing all of the memory usage.

Thus telling the GC to release the memory it have eaten is the only way to assure the correct work of the COM controls especially in the Win32 environments where the memory is limited to 2GB.

As I stated in the first sentence, when you begin to close documents after using them, the handle usage problem will be solved. But if your program would be up for a very long time there is a chance that there won't be enough memory for some operation. For example, int the Win32 process the GC is not releasing the memory as there is still 100MB left. You are launching some heavy operation that needs 150MB of free space to store it's temporary data. This won't happen as there is not enough memory for this operation.

Though these situations will statistically rarely happen as the GC will release the memory eventually and such cases are very usage specific and only for Win32. But telling it to release the memory forcefully will negate those few possible scenarios.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
AnKeilha
User
Posts: 63
Joined: Fri Apr 27, 2018 11:17 am

Re: accumulation of handles

Post by AnKeilha »

Hi Alex,
the Java Garbage Collector can only collect what is not referenced by another Object. That doesn't change when GC is called automatically by the JVM or it is triggered via the Java code using a System.gc()-call.

We close the IPXV_Document by using Close(). It doesn't matter, which PXV_DocCloseFlags we use (by the way - we couldn't find a documentation for PXV_DocClose_AllowAsync), after the GC ran, the handles are still there. And when trying to delete the named temporary directories manually (the ones that were created for the previously shown documents - starting with pdfx-), Windows tells us, that they can't be deleted, because they are still used by another process (the java process with the embedded PDFXChangeEditor).

We don't hold references to the IPXV_Documents. So somehow it seems like something within the PDFXChangeEditor keeps referencing the closed IPXV_Documents and/or the directories that were created while opening them. We tried a few things like cleaning history, disabling 'Documents -> Back/Forward commands navigate through all opened documents' or explicitly setting the open doc param 'CanAddToHistory' to false. But nothing solved the handles-problem...

When shutting down the application, all the directories are cleaned, unlocked but not deleted. So somehow some Object within the embedded PDFXChangeEditor seems to know all the directories that were created and need to be cleaned.

Regards
Andreas
AnKeilha
User
Posts: 63
Joined: Fri Apr 27, 2018 11:17 am

Re: accumulation of handles

Post by AnKeilha »

Another maybe important information is that the number of GDI objects keeps rising, when displaying new PDFs. When we have one embedded PDFXChangeEditor and open a new document via the said method (API function OpenDocFromPath()), at least one new GDI object seems to be created. We used the nice tool GDIView from nirsoft (Freeware) to find out, what objects are created. They are of type DC (Device Context). There is a limit of 10.000 per Windows process. After reaching this limit, the application more or less crashes, which is our main problem... There might be users that open that many documents in the course of time while searching for something specific.

Corresponding Screenshots of the tool:

- GDI-Objects at the beginning
GDI-Objects before.png
- GDI-Objects after a few new pdfs:
GDI-Objects after a few new pdfs.png
- GDI-Objects after a few hundred pdfs:
GDI-Objects after a few hundred pdfs.png
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: accumulation of handles

Post by Sasha - Tracker Dev Team »

Hello Andreas,

Let's do some synthetic testing.
1) Create a simple no IPXV_Control program that opens one document 100 times without calling Close() and show some kind of message box in the end so that the main method won't exit. Then check he handles.
2) Create a simple no IPXV_Control program that opens one document 100 times with calling Close() and show some kind of message box in the end so that the main method won't exit. Then check he handles.

As for the GDI - we don't actively use this for drawing and we do not hold any handles - if needed, we use the DS and then release it.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
AnKeilha
User
Posts: 63
Joined: Fri Apr 27, 2018 11:17 am

Re: accumulation of handles

Post by AnKeilha »

Hello Alex,
we've created a simple program that uses SWTs OleFrame to embed the PDFXChangeEditor. We are using JDK 1.8.0_161 to run it:
GDILeakTester.zip
(1.84 KiB) Downloaded 65 times
To actually be able to run it, you would also need some generated classes which are part of our project and are therefore confidential. I hope that, even without actually running it, you can see what we are doing.
Program started.png
In the upper area you have a text field where you can enter the PDFs that should be opened (see our - very ordinary - PDFs attached:
Test-PDFs.zip
(227.79 KiB) Downloaded 67 times
). You can enter a single PDF or multiple PDFs (separated by ,). You also have a spinner to say how many times the PDFs should be opened. Then you have a checkbox to indicate if you wish to explicitly close a document while opening a new one. And then you have the button to start the whole processing. It is set to run in single document mode.

We found out that the number of GDI-Objects is increased after the OpenDocFromPath()-call, but only when ctrl.Doc() was called at least once in the meantime:
Program with open and close.png
Surprisingly the GDI-Objects are not increased when we unset the checkbox to close the previously shown documents (and therefore ctrl.Doc() is not called).

Unfortunately, in our real world application, we have to call ctrl.Doc() to do various things (e.g. export comments as XFDF). Any suggestions?

Cheers
Andreas
AnKeilha
User
Posts: 63
Joined: Fri Apr 27, 2018 11:17 am

Re: accumulation of handles

Post by AnKeilha »

BTW: The above testing was done using PDFXChange Editor SDK 8.0, build 331.0
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: accumulation of handles

Post by Sasha - Tracker Dev Team »

Hello Andreas,

As you probably have seen for now, if you are using the ctrl.Doc() - the Java holds down the object with all of it's resources. Basically what you need is to release those objects and everything will work as intended.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
AnKeilha
User
Posts: 63
Joined: Fri Apr 27, 2018 11:17 am

Re: accumulation of handles

Post by AnKeilha »

Well, is there any API call that would release the operating system's resources (close() does not work)? As mentioned above using ctrl.Doc() is something we have to do for various reasons.
AnKeilha
User
Posts: 63
Joined: Fri Apr 27, 2018 11:17 am

Re: accumulation of handles

Post by AnKeilha »

Hello again,
just as reminder/caveat: We are using Ctrl instead of Inst because we have to control two separate OLE-embedded PDFXChange-Editors within the same process.

Regards,
Andreas
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: accumulation of handles

Post by Sasha - Tracker Dev Team »

Hello Andreas,

We do not hold these objects - Java does. Thus you will have to either to find a way so that Java won't hold these objects or release them after usage.
One of the ways to solve this is to make a non-Java/non-.Net wrapper that would do all of the logic that you require and you won't access the objects directly just their data or properties.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
Post Reply