[ 
https://issues.apache.org/jira/browse/PDFBOX-2592?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14272725#comment-14272725
 ] 

John Hewson commented on PDFBOX-2592:
-------------------------------------

No, the dispose() method has no impact on the GC of _managed objects_. It's 
just a naming convention for methods which close _native resources_. Note that 
"native resources" in .NET are pointers, handles and data buffers obtained from 
unmanned code via P/Invoke, i.e. low-level introp with C APIs which require 
calls to free() or similar once they are no longer needed - the Java equivalent 
is JNI.

The same concept can be seen in Java with the Graphics#close() method. The 
Graphics class opens various native resources (Java calls these "system 
resources") effectively via JNI, e.g. an OpenGL context, or a HBITMAP on 
Windows - these resources are obtained via C APIs and the corresponding close() 
and free() methods on them need to be called to avoid a memory leak. The 
convention is to call dispose() in the finalizer of the object which opened the 
resource; the user can call dispose() earlier if they don't want to wait for GC 
- but this wait is only because _native resources are invisible to the GC_, if 
your class holds a pointer to a 1GB native backing buffer obtained via JNI, all 
the GC can see is one 32 or 64-bit pointer, so there's no memory pressure, and 
thus the GC will keep waiting until there is enough managed garbage to bother 
collecting.

So you see, dispose() only applies to native resources (i.e. pointers to data 
elsewhere) obtained via JNI (aka P/Invoke on .NET) and not managed objects, 
which are GC'd as normal.

> Allow sharing of COS objects between different documents
> --------------------------------------------------------
>
>                 Key: PDFBOX-2592
>                 URL: https://issues.apache.org/jira/browse/PDFBOX-2592
>             Project: PDFBox
>          Issue Type: Improvement
>          Components: PDModel
>    Affects Versions: 2.0.0
>            Reporter: John Hewson
>            Assignee: John Hewson
>         Attachments: PDFBOX-2592.patch
>
>
> A number of users on the mailing list have asked about how to import pages 
> from other PDFs as forms, our current solution is LayerUtility, which is 
> depends on PDFCloneUtility. Both these classes are surprisingly complex for 
> what should be a simple task.
> The two main tasks which these classes perform is copying the page's 
> COSStream and cloning every relevant COS object. However, there seems to be 
> no real need to do any of this copying and cloning - there's nothing about 
> any of the COS objects which is specific to a given document. While a 
> COSStream can share the same backing file as the COSDocument, this isn't a 
> problem for COSWriter, even then we need only make sure that an exception is 
> thrown if a COSStream is used after its parent COSDocument is closed.
> Note that there *is* one artificial dependency between COSDictionary and 
> COSArrays and their parent COSDocument, that is that calling close() on the 
> COSDocument clears the contents of all child COSDictionary and COSArrays. 
> However, there's no need for this, it seems to have come about due to some 
> long past confusion regarding how garbage collection works in Java - we all 
> know that it's not necessary to set objects to null or clear lists when we 
> are done with them.
> I propose that we get rid of the unnecessary object and list clearing in 
> COSDocument#close() and add some checks to COSStream to throw user-friendly 
> exceptions when reading from a closed backing stream. This will allow us to 
> directly share COS objects between different COSDocuments, allowing simple "x 
> = y" copying and making LayerUtility and PDFCloneUtility unnecessary. Instead 
> of:
> {code}
> COSStream pageStream = (COSStream)page.getStream().getCOSObject();
> PDStream newStream = new PDStream(targetDoc, 
> pageStream.getUnfilteredStream(), false);
> PDFormXObject form = new PDFormXObject(newStream);
> PDResources pageRes = page.getResources();
> PDResources formRes = new PDResources();
> PDFCloneUtility cloner = new PDFCloneUtility(document);
> cloner.cloneMerge(pageRes, formRes);
> form.setResources(formRes);
> {code}
> We could have:
> {code}
> PDFormXObject form = new PDFormXObject(page.getStream());
> form.setResources(page.getResources());
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to