-
Notifications
You must be signed in to change notification settings - Fork 24.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Release underlying resources when JS instance in GC'ed on iOS (#24405)
Summary: Our Blob implementation was very problematic because it didn't release its underlying resource when the JS instance was dealocated. The main issue is that the fetch polyfill uses blobs by default if the module is available, which causes large memory leaks. This fixes it by using the new jsi infra to attach a `jsi::HostObject` (`BlobCollector`) to `Blob` instances. This way when the `Blob` is collected, the `BlobCollector` also gets collected. Using the `jsi::HostObject` dtor we can schedule the cleanup of native resources. This is definitely not the ideal solution but otherwise it would require rewriting the whole module using TurboModules + jsi. Fixes #23801, #20352, #21092 [General] [Fixed] - [Blob] Release underlying resources when JS instance in GC'ed Pull Request resolved: #24405 Differential Revision: D15237418 Pulled By: cpojer fbshipit-source-id: 00a94a54b0b172fbc62324364b753d192ac7016a
- Loading branch information
1 parent
bfd0695
commit c5c79e5
Showing
6 changed files
with
130 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#import <jsi/jsi.h> | ||
|
||
using namespace facebook; | ||
|
||
@class RCTBlobManager; | ||
|
||
namespace facebook { | ||
namespace react { | ||
|
||
class JSI_EXPORT RCTBlobCollector : public jsi::HostObject { | ||
public: | ||
RCTBlobCollector(RCTBlobManager *blobManager, const std::string &blobId); | ||
~RCTBlobCollector(); | ||
|
||
static void install(RCTBlobManager *blobManager); | ||
|
||
private: | ||
const std::string blobId_; | ||
RCTBlobManager *blobManager_; | ||
}; | ||
|
||
} // namespace react | ||
} // namespace facebook |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#import "RCTBlobCollector.h" | ||
|
||
#import <React/RCTBridge+Private.h> | ||
#import "RCTBlobManager.h" | ||
|
||
namespace facebook { | ||
namespace react { | ||
|
||
RCTBlobCollector::RCTBlobCollector(RCTBlobManager *blobManager, const std::string &blobId) | ||
: blobId_(blobId), blobManager_(blobManager) {} | ||
|
||
RCTBlobCollector::~RCTBlobCollector() { | ||
RCTBlobManager *blobManager = blobManager_; | ||
NSString *blobId = [NSString stringWithUTF8String:blobId_.c_str()]; | ||
dispatch_async([blobManager_ methodQueue], ^{ | ||
[blobManager remove:blobId]; | ||
}); | ||
} | ||
|
||
void RCTBlobCollector::install(RCTBlobManager *blobManager) { | ||
__weak RCTCxxBridge *cxxBridge = (RCTCxxBridge *)blobManager.bridge; | ||
[cxxBridge dispatchBlock:^{ | ||
if (!cxxBridge || cxxBridge.runtime == nullptr) { | ||
return; | ||
} | ||
jsi::Runtime &runtime = *(jsi::Runtime *)cxxBridge.runtime; | ||
runtime.global().setProperty( | ||
runtime, | ||
"__blobCollectorProvider", | ||
jsi::Function::createFromHostFunction( | ||
runtime, | ||
jsi::PropNameID::forAscii(runtime, "__blobCollectorProvider"), | ||
1, | ||
[blobManager](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) { | ||
auto blobId = args[0].asString(rt).utf8(rt); | ||
auto blobCollector = std::make_shared<RCTBlobCollector>(blobManager, blobId); | ||
return jsi::Object::createFromHostObject(rt, blobCollector); | ||
} | ||
) | ||
); | ||
} queue:RCTJSThread]; | ||
} | ||
|
||
} // namespace react | ||
} // namespace facebook |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
c5c79e5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one!
c5c79e5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<B