Clean-up parent / owner reference of children during clonning

Summary: This diff cleans up the parent / owner references for children of ReactShadowNode / YogaNode during cloning. The reason of this behavior is to avoid retaining every generation of trees during cloning. This fixes a memory leak detected when running the ProgressBarExample.android.js in catalyst app

Reviewed By: fkgozali

Differential Revision: D8019894

fbshipit-source-id: b0d38f0c836ffec534f64fa1adbd7511ecf3473d
This commit is contained in:
David Vacca 2018-06-22 11:29:05 -07:00 committed by Facebook Github Bot
parent 74627d4833
commit f19c36116c
3 changed files with 31 additions and 9 deletions

View File

@ -193,12 +193,24 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
// Virtual ReactShadowNode do not have a YogaNode associated
copy.mYogaNode = null;
}
copy.mNativeChildren = mNativeChildren == null ? null : new ArrayList<>(mNativeChildren);
copy.mTotalNativeChildren = mTotalNativeChildren;
copy.mChildren = mChildren == null ? null : new ArrayList<>(mChildren);
copy.mNativeChildren = copyChildren(mNativeChildren);
copy.mChildren = copyChildren(mChildren);
return copy;
}
@Nullable
private ArrayList<ReactShadowNodeImpl> copyChildren(@Nullable List<ReactShadowNodeImpl> list){
ArrayList<ReactShadowNodeImpl> result = list == null ? null : new ArrayList<>(list);
if (result != null) {
for (ReactShadowNodeImpl child : result) {
child.mParent = null;
}
}
return result;
}
@Override
public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) {
ReactShadowNodeImpl copy = copy();

View File

@ -1,8 +1,9 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.yoga;
@ -185,6 +186,11 @@ public class YogaNode implements Cloneable {
clonedYogaNode.mOwner = null;
clonedYogaNode.mChildren =
mChildren != null ? (List<YogaNode>) ((ArrayList) mChildren).clone() : null;
if (clonedYogaNode.mChildren != null) {
for (YogaNode child : clonedYogaNode.mChildren) {
child.mOwner = null;
}
}
return clonedYogaNode;
} catch (CloneNotSupportedException ex) {
// This class implements Cloneable, this should not happen

View File

@ -1,8 +1,9 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
/*
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "Yoga.h"
@ -243,6 +244,9 @@ YGNodeRef YGNodeClone(YGNodeRef oldNode) {
oldNode->getConfig(),
node != nullptr,
"Could not allocate memory for node");
for (auto &item : oldNode->getChildren()) {
item->setOwner(nullptr);
}
gNodeInstanceCount++;
node->setOwner(nullptr);
return node;