Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: content/browser/memory/memory_coordinator_impl_unittest.cc

Issue 2763933002: memory coordinator: Purge memory under memory pressure (Closed)
Patch Set: comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/memory/memory_coordinator_impl.h" 5 #include "content/browser/memory/memory_coordinator_impl.h"
6 6
7 #include "base/memory/memory_coordinator_client_registry.h" 7 #include "base/memory/memory_coordinator_client_registry.h"
8 #include "base/memory/memory_coordinator_proxy.h" 8 #include "base/memory/memory_coordinator_proxy.h"
9 #include "base/memory/memory_pressure_monitor.h" 9 #include "base/memory/memory_pressure_monitor.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 59
60 // A mock MemoryCoordinatorClient, for testing interaction between MC and 60 // A mock MemoryCoordinatorClient, for testing interaction between MC and
61 // clients. 61 // clients.
62 class MockMemoryCoordinatorClient : public base::MemoryCoordinatorClient { 62 class MockMemoryCoordinatorClient : public base::MemoryCoordinatorClient {
63 public: 63 public:
64 void OnMemoryStateChange(base::MemoryState state) override { 64 void OnMemoryStateChange(base::MemoryState state) override {
65 did_state_changed_ = true; 65 did_state_changed_ = true;
66 state_ = state; 66 state_ = state;
67 } 67 }
68 68
69 void OnPurgeMemory() override { ++purge_memory_calls_; }
70
69 bool did_state_changed() const { return did_state_changed_; } 71 bool did_state_changed() const { return did_state_changed_; }
70 base::MemoryState state() const { return state_; } 72 base::MemoryState state() const { return state_; }
73 int purge_memory_calls() const { return purge_memory_calls_; }
71 74
72 private: 75 private:
73 bool did_state_changed_ = false; 76 bool did_state_changed_ = false;
74 base::MemoryState state_ = base::MemoryState::NORMAL; 77 base::MemoryState state_ = base::MemoryState::NORMAL;
78 int purge_memory_calls_ = 0;
75 }; 79 };
76 80
77 class MockMemoryMonitor : public MemoryMonitor { 81 class MockMemoryMonitor : public MemoryMonitor {
78 public: 82 public:
79 MockMemoryMonitor() {} 83 MockMemoryMonitor() {}
80 ~MockMemoryMonitor() override {} 84 ~MockMemoryMonitor() override {}
81 85
82 void SetFreeMemoryUntilCriticalMB(int free_memory) { 86 void SetFreeMemoryUntilCriticalMB(int free_memory) {
83 free_memory_ = free_memory; 87 free_memory_ = free_memory;
84 } 88 }
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 EXPECT_EQ(2, delegate->discard_tab_count()); 563 EXPECT_EQ(2, delegate->discard_tab_count());
560 564
561 // Back to NORMAL. Tab discarding should stop. 565 // Back to NORMAL. Tab discarding should stop.
562 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); 566 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50);
563 task_runner_->FastForwardBy(interval); 567 task_runner_->FastForwardBy(interval);
564 EXPECT_EQ(2, delegate->discard_tab_count()); 568 EXPECT_EQ(2, delegate->discard_tab_count());
565 task_runner_->FastForwardBy(interval); 569 task_runner_->FastForwardBy(interval);
566 EXPECT_EQ(2, delegate->discard_tab_count()); 570 EXPECT_EQ(2, delegate->discard_tab_count());
567 } 571 }
568 572
573 TEST_F(MemoryCoordinatorImplTest, OnWarningCondition) {
574 MockMemoryCoordinatorClient client;
575 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client);
576 auto* child1 = coordinator_->CreateChildMemoryCoordinator(1);
577 auto* child2 = coordinator_->CreateChildMemoryCoordinator(2);
578 base::TimeDelta interval = base::TimeDelta::FromSeconds(31);
579
580 // child1: Foreground, child2: Background
581 coordinator_->OnChildVisibilityChanged(1, true);
582 coordinator_->OnChildVisibilityChanged(2, false);
583
584 // Note: we never ask foreground processes (including the browser process) to
585 // purge memory on WARNING condition.
586
587 // Don't ask the background child to purge until the child remains
588 // backgrounded for a certain period of time.
589 coordinator_->OnWarningCondition();
590 RunUntilIdle();
591 EXPECT_EQ(0, client.purge_memory_calls());
592 EXPECT_EQ(0, child1->purge_memory_calls());
593 EXPECT_EQ(0, child2->purge_memory_calls());
594
595 // After a certain period of time is passed, request the child to purge
596 // memory.
597 task_runner_->FastForwardBy(interval);
598 coordinator_->OnWarningCondition();
599 task_runner_->RunUntilIdle();
600 RunUntilIdle();
601 EXPECT_EQ(0, client.purge_memory_calls());
602 EXPECT_EQ(0, child1->purge_memory_calls());
603 EXPECT_EQ(1, child2->purge_memory_calls());
604
605 // Don't purge memory more than once when the child stays backgrounded.
606 task_runner_->FastForwardBy(interval);
607 coordinator_->OnWarningCondition();
608 RunUntilIdle();
609 EXPECT_EQ(0, client.purge_memory_calls());
610 EXPECT_EQ(0, child1->purge_memory_calls());
611 EXPECT_EQ(1, child2->purge_memory_calls());
612
613 // The background child goes to foreground, goes to background, then a
614 // certain period of time is passed. Another purging request should be sent.
615 coordinator_->OnChildVisibilityChanged(2, true);
616 coordinator_->OnChildVisibilityChanged(2, false);
617 task_runner_->FastForwardBy(interval);
618 coordinator_->OnWarningCondition();
619 RunUntilIdle();
620 EXPECT_EQ(0, client.purge_memory_calls());
621 EXPECT_EQ(0, child1->purge_memory_calls());
622 EXPECT_EQ(2, child2->purge_memory_calls());
623
624 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client);
625 }
626
627 TEST_F(MemoryCoordinatorImplTest, OnCriticalCondition) {
628 MockMemoryCoordinatorClient client;
629 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client);
630 auto* child1 = coordinator_->CreateChildMemoryCoordinator(1);
631 auto* child2 = coordinator_->CreateChildMemoryCoordinator(2);
632 auto* delegate = coordinator_->GetDelegate();
633 base::TimeDelta interval = base::TimeDelta::FromSeconds(31);
634
635 // child1: Foreground, child2: Background
636 coordinator_->OnChildVisibilityChanged(1, true);
637 coordinator_->OnChildVisibilityChanged(2, false);
638
639 // Purge memory from all children regardless of their visibility.
640 task_runner_->FastForwardBy(interval);
641 coordinator_->OnCriticalCondition();
642 RunUntilIdle();
643 task_runner_->FastForwardBy(interval);
644 coordinator_->OnCriticalCondition();
645 RunUntilIdle();
646 EXPECT_EQ(2, delegate->discard_tab_count());
647 EXPECT_EQ(0, client.purge_memory_calls());
648 EXPECT_EQ(1, child1->purge_memory_calls());
649 EXPECT_EQ(1, child2->purge_memory_calls());
650
651 // Purge memory from browser process only after we asked all children to
652 // purge memory.
653 task_runner_->FastForwardBy(interval);
654 coordinator_->OnCriticalCondition();
655 RunUntilIdle();
656 EXPECT_EQ(3, delegate->discard_tab_count());
657 EXPECT_EQ(1, client.purge_memory_calls());
658 EXPECT_EQ(1, child1->purge_memory_calls());
659 EXPECT_EQ(1, child2->purge_memory_calls());
660
661 // Don't request purging for a certain period of time if we already requested.
662 task_runner_->FastForwardBy(interval);
663 coordinator_->OnCriticalCondition();
664 RunUntilIdle();
665 EXPECT_EQ(4, delegate->discard_tab_count());
666 EXPECT_EQ(1, client.purge_memory_calls());
667 EXPECT_EQ(1, child1->purge_memory_calls());
668 EXPECT_EQ(1, child2->purge_memory_calls());
669
670 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client);
671 }
672
569 #if defined(OS_ANDROID) 673 #if defined(OS_ANDROID)
570 // TODO(jcivelli): Broken on Android. http://crbug.com/678665 674 // TODO(jcivelli): Broken on Android. http://crbug.com/678665
571 #define MAYBE_GetStateForProcess DISABLED_GetStateForProcess 675 #define MAYBE_GetStateForProcess DISABLED_GetStateForProcess
572 #else 676 #else
573 #define MAYBE_GetStateForProcess GetStateForProcess 677 #define MAYBE_GetStateForProcess GetStateForProcess
574 #endif 678 #endif
575 TEST_F(MemoryCoordinatorImplTest, MAYBE_GetStateForProcess) { 679 TEST_F(MemoryCoordinatorImplTest, MAYBE_GetStateForProcess) {
576 EXPECT_EQ(base::MemoryState::UNKNOWN, 680 EXPECT_EQ(base::MemoryState::UNKNOWN,
577 coordinator_->GetStateForProcess(base::kNullProcessHandle)); 681 coordinator_->GetStateForProcess(base::kNullProcessHandle));
578 EXPECT_EQ(base::MemoryState::NORMAL, 682 EXPECT_EQ(base::MemoryState::NORMAL,
(...skipping 19 matching lines...) Expand all
598 702
599 EXPECT_TRUE( 703 EXPECT_TRUE(
600 coordinator_->SetChildMemoryState(1, MemoryState::THROTTLED)); 704 coordinator_->SetChildMemoryState(1, MemoryState::THROTTLED));
601 EXPECT_EQ(base::MemoryState::THROTTLED, 705 EXPECT_EQ(base::MemoryState::THROTTLED,
602 coordinator_->GetStateForProcess(process1.Handle())); 706 coordinator_->GetStateForProcess(process1.Handle()));
603 EXPECT_EQ(base::MemoryState::NORMAL, 707 EXPECT_EQ(base::MemoryState::NORMAL,
604 coordinator_->GetStateForProcess(process2.Handle())); 708 coordinator_->GetStateForProcess(process2.Handle()));
605 } 709 }
606 710
607 } // namespace content 711 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/memory/memory_coordinator_impl.cc ('k') | content/renderer/render_thread_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698