Author: mduerig
Date: Thu Apr 20 10:36:35 2017
New Revision: 1792037

URL: http://svn.apache.org/viewvc?rev=1792037&view=rev
Log:
OAK-6106: Excessive memory usage by the cached segment references
Cache the segment references as msb, lsb pairs instead of SegmentId instances

Modified:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java?rev=1792037&r1=1792036&r2=1792037&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
 Thu Apr 20 10:36:35 2017
@@ -255,25 +255,31 @@ public class Segment {
 
         final int referencedSegmentIdCount = getReferencedSegmentIdCount();
         final int refOffset = data.position() + HEADER_SIZE;
-        final SegmentId[] refIds = new SegmentId[referencedSegmentIdCount];
+
+        // lazily populated cache of msbs and lsbs of the referenced segments 
ids.
+        // DO NOT keep references to the SegmentIds here as this will overflow 
the heap.
+        // See OAK-4949.
+        final long[] ids = new long[2 * referencedSegmentIdCount];
         return new SegmentReferences() {
             @Override
             public SegmentId getSegmentId(int reference) {
                 checkArgument(reference <= referencedSegmentIdCount, "Segment 
reference out of bounds");
-                SegmentId id = refIds[reference - 1];
-                if (id == null) {
-                    synchronized(refIds) {
-                        id = refIds[reference - 1];
-                        if (id == null) {
+                long msb = ids[2*(reference - 1)];
+                long lsb = ids[2*(reference - 1) + 1];
+                if (lsb == 0 && msb == 0) {
+                    synchronized(ids) {
+                        msb = ids[2*(reference - 1)];
+                        lsb = ids[2*(reference - 1) + 1];
+                        if (lsb == 0 && msb == 0) {
                             int position = refOffset + (reference - 1) * 
SEGMENT_REFERENCE_SIZE;
-                            long msb = data.getLong(position);
-                            long lsb = data.getLong(position + 8);
-                            id = idProvider.newSegmentId(msb, lsb);
-                            refIds[reference - 1] = id;
+                            msb = data.getLong(position);
+                            lsb = data.getLong(position + 8);
+                            ids[2*(reference - 1)] = msb;
+                            ids[2*(reference - 1) + 1] = lsb;
                         }
                     }
                 }
-                return id;
+                return idProvider.newSegmentId(msb, lsb);
             }
 
             @Nonnull


Reply via email to