-
Notifications
You must be signed in to change notification settings - Fork 28.4k
Unable to release FlutterViewController even when there is nothing referencing it. #21347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
cc @jamesderlin |
Is there any progress? |
cc @dnfield |
flutter/engine#6464 This should be related to the retain circles. |
flutter/engine#6447 should make this more doable. I'm curious about the Skia images leaking though, do you have a reproduction for that by chance? |
It just happens when you dealloc shell inside FlutterViewController. When I tried to release shell, the Skia Objects unref operation causes a crash for null pointer exceptions. When I tried to avoid the crashes by skipping the unref operation the leaks happened. My guess is that the Skia images have to be released on GPU thread and there were some threads synchronization problems. It could be related to code blow. shell deconstructor: Shell::~Shell() {
PersistentCache::GetCacheForProcess()->RemoveWorkerTaskRunner(
task_runners_.GetIOTaskRunner());
if (auto vm = blink::DartVM::ForProcessIfInitialized()) {
vm->GetServiceProtocol().RemoveHandler(this);
}
fml::AutoResetWaitableEvent ui_latch, gpu_latch, platform_latch, io_latch;
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetUITaskRunner(),
fml::MakeCopyable([engine = std::move(engine_), &ui_latch]() mutable {
engine.reset();
ui_latch.Signal();
}));
ui_latch.Wait();
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetGPUTaskRunner(),
fml::MakeCopyable(
[rasterizer = std::move(rasterizer_), &gpu_latch]() mutable {
rasterizer.reset();
gpu_latch.Signal();
}));
gpu_latch.Wait();
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetIOTaskRunner(),
fml::MakeCopyable([io_manager = std::move(io_manager_),
platform_view = platform_view_.get(),
&io_latch]() mutable {
io_manager.reset();
if (platform_view) {
platform_view->ReleaseResourceContext();
}
io_latch.Signal();
}));
io_latch.Wait();
// The platform view must go last because it may be holding onto platform side
// counterparts to resources owned by subsystems running on other threads. For
// example, the NSOpenGLContext on the Mac.
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetPlatformTaskRunner(),
fml::MakeCopyable([platform_view = std::move(platform_view_),
&platform_latch]() mutable {
platform_view.reset();
platform_latch.Signal();
}));
platform_latch.Wait();
} unref code: void SkiaUnrefQueue::Unref(SkRefCnt* object) {
std::lock_guard<std::mutex> lock(mutex_);
objects_.push_back(object);
if (!drain_pending_) {
drain_pending_ = true;
task_runner_->PostDelayedTask(
[strong = fml::Ref(this)]() { strong->Drain(); }, drain_delay_);
}
}
void SkiaUnrefQueue::Drain() {
std::deque<SkRefCnt*> skia_objects;
{
std::lock_guard<std::mutex> lock(mutex_);
objects_.swap(skia_objects);
drain_pending_ = false;
}
for (SkRefCnt* skia_object : skia_objects) {
skia_object->unref();
}
}
|
Please notice this problem was on 0.5.6 beta version. |
Can you try with the code in flutter/engine#6447 and see if you're able to successfully release the view controller without memory leaks? I don't know if I'm doing exactly what you did, but I'm pretty sure it should work with that patch. |
@dnfield I didn't see the same problems so far. I will continue investigate. For now I should just close the issue for this particular problem. Thanks! |
@nightwolf-chen @dnfield I have this problem in flutter release 1.0
|
@firetheworld sounds like #25255 |
Call flutterEngine?.destroyContext() when you want release flutterViewController |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of |
We‘ve embed Flutter into our existing App. The problem is that we want to release FlutterViewController when there are no Flutter Pages to save some memory. But we found that FlutterViewController can't be released even there are no references to it.
I've debug into Flutter Engine and found that there are some retain circles between FlutterChannels and FlutterViewController. I tried to break the retain circles and released FlutterViewController successfully. But there are some Skia Images leaked during the release of FlutterViewController.
I was wondering is there any official support for FlutterViewController releasing and rebuilding without those memory leak problems.
The text was updated successfully, but these errors were encountered: