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