HDFS-14492. Snapshot memory leak. Contributed by Wei-Chiu Chuang. (#1370)

* HDFS-14492. Snapshot memory leak. Contributed by Wei-Chiu Chuang.

Change-Id: I9e5e450c07ad70aa1905973896c4f627042dbd37

* Fix checkstyle

Change-Id: I16d4bd4f03a971e1ed36cf57d89dc42357ef8fbf
(cherry picked from commit 6ef6594c7e)
(cherry picked from commit 570ffa1cd6)
This commit is contained in:
Wei-Chiu Chuang 2019-10-01 08:46:46 -07:00 committed by Wei-Chiu Chuang
parent e640e809a9
commit a3493fe328
5 changed files with 15 additions and 15 deletions

View File

@ -838,6 +838,12 @@ public class INodeDirectory extends INodeWithAdditionalFields
// there is snapshot data // there is snapshot data
if (sf != null) { if (sf != null) {
sf.cleanDirectory(reclaimContext, this, snapshotId, priorSnapshotId); sf.cleanDirectory(reclaimContext, this, snapshotId, priorSnapshotId);
// If the inode has empty diff list and sf is not a
// DirectorySnapshottableFeature, remove the feature to save heap.
if (sf.getDiffs().isEmpty() &&
!(sf instanceof DirectorySnapshottableFeature)) {
this.removeFeature(sf);
}
} else { } else {
// there is no snapshot data // there is no snapshot data
if (priorSnapshotId == Snapshot.NO_SNAPSHOT_ID && if (priorSnapshotId == Snapshot.NO_SNAPSHOT_ID &&

View File

@ -744,6 +744,9 @@ public class INodeFile extends INodeWithAdditionalFields
sf.cleanFile(reclaimContext, this, snapshot, priorSnapshotId, sf.cleanFile(reclaimContext, this, snapshot, priorSnapshotId,
getStoragePolicyID()); getStoragePolicyID());
updateRemovedUnderConstructionFiles(reclaimContext); updateRemovedUnderConstructionFiles(reclaimContext);
if (sf.getDiffs().isEmpty()) {
this.removeFeature(sf);
}
} else { } else {
if (snapshot == CURRENT_STATE_ID) { if (snapshot == CURRENT_STATE_ID) {
if (priorSnapshotId == NO_SNAPSHOT_ID) { if (priorSnapshotId == NO_SNAPSHOT_ID) {

View File

@ -45,6 +45,10 @@ abstract class AbstractINodeDiffList<N extends INode,
return diffs != null ? return diffs != null ?
DiffList.unmodifiableList(diffs) : DiffList.emptyList(); DiffList.unmodifiableList(diffs) : DiffList.emptyList();
} }
public boolean isEmpty() {
return diffs == null || diffs.isEmpty();
}
/** Clear the list. */ /** Clear the list. */
public void clear() { public void clear() {

View File

@ -2141,24 +2141,11 @@ public class TestRenameWithSnapshots {
INodeDirectory dir2Node = fsdir.getINode4Write(dir2.toString()) INodeDirectory dir2Node = fsdir.getINode4Write(dir2.toString())
.asDirectory(); .asDirectory();
assertTrue("the diff list of " + dir2 assertTrue("the diff list of " + dir2
+ " should be empty after deleting s0", dir2Node.getDiffs().asList() + " should be empty after deleting s0", !dir2Node.isWithSnapshot());
.isEmpty());
assertTrue(hdfs.exists(newfoo)); assertTrue(hdfs.exists(newfoo));
INode fooRefNode = fsdir.getINode4Write(newfoo.toString()); INode fooRefNode = fsdir.getINode4Write(newfoo.toString());
assertTrue(fooRefNode instanceof INodeReference.DstReference); assertTrue(fooRefNode instanceof INodeReference.DstReference);
INodeDirectory fooNode = fooRefNode.asDirectory();
// fooNode should be still INodeDirectory (With Snapshot) since we call
// recordModification before the rename
assertTrue(fooNode.isWithSnapshot());
assertTrue(fooNode.getDiffs().asList().isEmpty());
INodeDirectory barNode = fooNode.getChildrenList(Snapshot.CURRENT_STATE_ID)
.get(0).asDirectory();
// bar should also be INodeDirectory (With Snapshot), and both of its diff
// list and children list are empty
assertTrue(barNode.getDiffs().asList().isEmpty());
assertTrue(barNode.getChildrenList(Snapshot.CURRENT_STATE_ID).isEmpty());
restartClusterAndCheckImage(true); restartClusterAndCheckImage(true);
} }

View File

@ -527,7 +527,7 @@ public class TestSnapshotDeletion {
assertEquals(snapshot1.getId(), diffList.getLast().getSnapshotId()); assertEquals(snapshot1.getId(), diffList.getLast().getSnapshotId());
diffList = fsdir.getINode(metaChangeDir.toString()).asDirectory() diffList = fsdir.getINode(metaChangeDir.toString()).asDirectory()
.getDiffs(); .getDiffs();
assertEquals(0, diffList.asList().size()); assertEquals(null, diffList);
// check 2. noChangeDir and noChangeFile are still there // check 2. noChangeDir and noChangeFile are still there
final INodeDirectory noChangeDirNode = final INodeDirectory noChangeDirNode =