Agneta Walterscheidt created FOP-2606:
-----------------------------------------

             Summary: Save memory by clearing Markers
                 Key: FOP-2606
                 URL: https://issues.apache.org/jira/browse/FOP-2606
             Project: FOP
          Issue Type: Improvement
          Components: fo/page
    Affects Versions: 2.1
         Environment: all
            Reporter: Agneta Walterscheidt
            Priority: Minor


When one of my fop transformations went out of memory I inspected the heap dump 
and found many instances of PageViewport.pageMarkers. These markers are kept 
for all pages although - as far as I see - for processed pages only the 
"last-within-page" markers are needed. Moreover the processed pages are 
searched from back to front which means that it would be sufficient to keep one 
marker instance for the page-sequence (=> throw away when a new page-sequence 
starts) and one instance for the document (=> never throw away) and there 
replace older markers with newer markers.
I have implemented these changes on the trunk files and executed the build 
including the tests. You find a patch below.
I think the best implementation depends on some decisions, for instance where 
the markers should be kept. Therefore could you please either integrate my 
changes or implement a similar solution?

Index: area/AreaTreeModel.java
===================================================================
--- area/AreaTreeModel.java     (revision 1742452)
+++ area/AreaTreeModel.java     (working copy)
@@ -27,6 +27,10 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.fop.fo.flow.AbstractRetrieveMarker;
+import org.apache.fop.fo.flow.Marker;
+import org.apache.fop.fo.flow.Markers;
+import org.apache.fop.fo.flow.RetrieveMarker;
 
 /**
  * This is the model for the area tree object.
@@ -42,6 +46,11 @@
 
     /** the current page sequence */
     protected PageSequence currentPageSequence;
+    
+       Markers documentMarkers = new Markers();
+
+       Markers pageSequenceMarkers;
+
     /** logger instance */
     protected static final Log log = LogFactory.getLog(AreaTreeModel.class);
 
@@ -64,6 +73,7 @@
             currentPageIndex += currentPageSequence.getPageCount();
         }
         this.currentPageSequence = pageSequence;
+        pageSequenceMarkers = null;
         pageSequenceList.add(currentPageSequence);
     }
 
@@ -77,7 +87,29 @@
                 + currentPageSequence.getPageCount() - 1);
         page.setPageSequence(currentPageSequence);
     }
+    
+       public void addMarkers(Markers markers) {
+               if (markers != null) {
+                       if (pageSequenceMarkers == null) {
+                               pageSequenceMarkers = markers;
+                       } else {
+                               pageSequenceMarkers.add(markers);
+                       }
+                       documentMarkers.add(markers);
+               }
+       }
 
+       public Marker resolveMarker(AbstractRetrieveMarker arm, boolean doc) {
+               Marker mark = null;
+               if (pageSequenceMarkers != null) {
+                       mark = pageSequenceMarkers.resolve(arm);
+               }
+               if (mark == null && doc) {
+                       mark = documentMarkers.resolve(arm);
+               }
+               return mark;
+       }
+
     /**
      * Handle an OffDocumentItem
      * @param ext the extension to handle
Index: area/PageViewport.java
===================================================================
--- area/PageViewport.java      (revision 1742452)
+++ area/PageViewport.java      (working copy)
@@ -538,4 +538,13 @@
         }
     }
 
+       public Markers removeMarkers() {
+               if (pageMarkers == null) {
+                       return null;
+               }
+               Markers markers = pageMarkers.createLastMarkers();
+               pageMarkers = null;
+               return markers;
+       }
+
 }
Index: fo/flow/Markers.java
===================================================================
--- fo/flow/Markers.java        (revision 1742452)
+++ fo/flow/Markers.java        (working copy)
@@ -213,4 +213,51 @@
         }
     }
 
+       public Markers createLastMarkers() {
+               Markers markers = null;
+               if (lastQualifyingIsAny != null) {
+                       markers = new Markers();
+                       markers.lastQualifyingIsAny = new HashMap<String, 
Marker>(lastQualifyingIsAny);
+                       
+            if (lastQualifyingIsLast != null) {
+               markers.lastQualifyingIsAny.putAll(lastQualifyingIsLast);
+            }
+               }
+               return markers;
+       }
+
+       public void add(Markers markers) {
+               if (markers.firstQualifyingIsFirst != null) {
+                       if (firstQualifyingIsFirst == null) {
+                               firstQualifyingIsFirst = new HashMap<String, 
Marker>();
+                       }
+                       
firstQualifyingIsFirst.putAll(markers.firstQualifyingIsFirst);
+               }
+               if (markers.firstQualifyingIsAny != null) {
+                       if (firstQualifyingIsAny == null) {
+                               firstQualifyingIsAny = new HashMap<String, 
Marker>();
+                       }
+                       
firstQualifyingIsAny.putAll(markers.firstQualifyingIsAny);
+               }
+               if (markers.lastQualifyingIsFirst != null) {
+                       if (lastQualifyingIsFirst == null) {
+                               lastQualifyingIsFirst = new HashMap<String, 
Marker>();
+                       }
+                       
lastQualifyingIsFirst.putAll(markers.lastQualifyingIsFirst);
+               }
+               if (markers.lastQualifyingIsLast != null) {
+                       if (lastQualifyingIsLast == null) {
+                               lastQualifyingIsLast = new HashMap<String, 
Marker>();
+                       }
+                       
lastQualifyingIsLast.putAll(markers.lastQualifyingIsLast);
+               }
+               if (markers.lastQualifyingIsAny != null) {
+                       if (lastQualifyingIsAny == null) {
+                               lastQualifyingIsAny = new HashMap<String, 
Marker>();
+                       }
+                       lastQualifyingIsAny.putAll(markers.lastQualifyingIsAny);
+               }
+               
+       }
+
 }
Index: layoutmgr/AbstractPageSequenceLayoutManager.java
===================================================================
--- layoutmgr/AbstractPageSequenceLayoutManager.java    (revision 1742452)
+++ layoutmgr/AbstractPageSequenceLayoutManager.java    (working copy)
@@ -32,6 +32,7 @@
 import org.apache.fop.datatypes.Numeric;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.flow.Marker;
+import org.apache.fop.fo.flow.Markers;
 import org.apache.fop.fo.flow.RetrieveMarker;
 import org.apache.fop.fo.pagination.AbstractPageSequence;
 
@@ -231,31 +232,36 @@
         // get marker from the current markers on area tree
         Marker mark = getCurrentPV().resolveMarker(rm);
         if (mark == null && boundary != EN_PAGE) {
+            boolean doc = (boundary == EN_DOCUMENT);
+            int originalPosition = rm.getPosition();
+            rm.changePositionTo(Constants.EN_LEWP);
+               mark = areaTreeModel.resolveMarker(rm, doc);
+               rm.changePositionTo(originalPosition);
+               
             // go back over pages until mark found
             // if document boundary then keep going
-            boolean doc = (boundary == EN_DOCUMENT);
-            int seq = areaTreeModel.getPageSequenceCount();
-            int page = areaTreeModel.getPageCount(seq) - 1;
-            while (page < 0 && doc && seq > 1) {
-                seq--;
-                page = areaTreeModel.getPageCount(seq) - 1;
-            }
-            while (page >= 0) {
-                PageViewport pv = areaTreeModel.getPage(seq, page);
-                int originalPosition = rm.getPosition();
-                rm.changePositionTo(Constants.EN_LEWP);
-                mark = pv.resolveMarker(rm);
-                // this is probably not necessary since the RM will not be 
used again, but to be safe...
-                rm.changePositionTo(originalPosition);
-                if (mark != null) {
-                    break;
-                }
-                page--;
-                if (page < 0 && doc && seq > 1) {
-                    seq--;
-                    page = areaTreeModel.getPageCount(seq) - 1;
-                }
-            }
+//            int seq = areaTreeModel.getPageSequenceCount();
+//            int page = areaTreeModel.getPageCount(seq) - 1;
+//            while (page < 0 && doc && seq > 1) {
+//                seq--;
+//                page = areaTreeModel.getPageCount(seq) - 1;
+//            }
+//            while (page >= 0) {
+//                PageViewport pv = areaTreeModel.getPage(seq, page);
+//                int originalPosition = rm.getPosition();
+//                rm.changePositionTo(Constants.EN_LEWP);
+//                mark = pv.resolveMarker(rm);
+//                // this is probably not necessary since the RM will not be 
used again, but to be safe...
+//                rm.changePositionTo(originalPosition);
+//                if (mark != null) {
+//                    break;
+//                }
+//                page--;
+//                if (page < 0 && doc && seq > 1) {
+//                    seq--;
+//                    page = areaTreeModel.getPageCount(seq) - 1;
+//                }
+//            }
         }
 
         if (mark == null) {
@@ -317,6 +323,10 @@
             log.debug("page finished: " + 
curPage.getPageViewport().getPageNumberString()
                     + ", current num: " + currentPageNum);
         }
+        Markers markers = curPage.getPageViewport().removeMarkers();
+        if (markers != null) {
+               areaTreeHandler.getAreaTreeModel().addMarkers(markers);
+        }
         curPage = null;
     }



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

Reply via email to