OLD | NEW |
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 "storage/browser/blob/blob_memory_controller.h" | 5 #include "storage/browser/blob/blob_memory_controller.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <numeric> | 8 #include <numeric> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/callback.h" | 12 #include "base/callback.h" |
13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
14 #include "base/containers/small_map.h" | 14 #include "base/containers/small_map.h" |
15 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
16 #include "base/guid.h" | 16 #include "base/guid.h" |
17 #include "base/location.h" | 17 #include "base/location.h" |
18 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
| 19 #include "base/metrics/histogram_functions.h" |
19 #include "base/metrics/histogram_macros.h" | 20 #include "base/metrics/histogram_macros.h" |
20 #include "base/numerics/safe_conversions.h" | 21 #include "base/numerics/safe_conversions.h" |
21 #include "base/numerics/safe_math.h" | 22 #include "base/numerics/safe_math.h" |
22 #include "base/single_thread_task_runner.h" | 23 #include "base/single_thread_task_runner.h" |
23 #include "base/stl_util.h" | 24 #include "base/stl_util.h" |
24 #include "base/strings/string_number_conversions.h" | 25 #include "base/strings/string_number_conversions.h" |
25 #include "base/sys_info.h" | 26 #include "base/sys_info.h" |
26 #include "base/task_runner.h" | 27 #include "base/task_runner.h" |
27 #include "base/task_runner_util.h" | 28 #include "base/task_runner_util.h" |
28 #include "base/threading/thread_restrictions.h" | 29 #include "base/threading/thread_restrictions.h" |
29 #include "base/time/time.h" | 30 #include "base/time/time.h" |
30 #include "base/trace_event/trace_event.h" | 31 #include "base/trace_event/trace_event.h" |
31 #include "storage/browser/blob/blob_data_builder.h" | 32 #include "storage/browser/blob/blob_data_builder.h" |
32 #include "storage/browser/blob/blob_data_item.h" | 33 #include "storage/browser/blob/blob_data_item.h" |
33 #include "storage/browser/blob/shareable_blob_data_item.h" | 34 #include "storage/browser/blob/shareable_blob_data_item.h" |
34 #include "storage/browser/blob/shareable_file_reference.h" | 35 #include "storage/browser/blob/shareable_file_reference.h" |
35 #include "storage/common/data_element.h" | 36 #include "storage/common/data_element.h" |
36 | 37 |
37 using base::File; | 38 using base::File; |
38 using base::FilePath; | 39 using base::FilePath; |
39 | 40 |
40 namespace storage { | 41 namespace storage { |
41 namespace { | 42 namespace { |
42 constexpr int64_t kUnknownDiskAvailability = -1ll; | 43 constexpr int64_t kUnknownDiskAvailability = -1ll; |
43 constexpr uint64_t kMegabyte = 1024ull * 1024; | 44 constexpr uint64_t kMegabyte = 1024ull * 1024; |
| 45 const int64_t kMinSecondsForPressureEvictions = 30; |
44 | 46 |
45 using FileCreationInfo = BlobMemoryController::FileCreationInfo; | 47 using FileCreationInfo = BlobMemoryController::FileCreationInfo; |
46 using MemoryAllocation = BlobMemoryController::MemoryAllocation; | 48 using MemoryAllocation = BlobMemoryController::MemoryAllocation; |
47 using QuotaAllocationTask = BlobMemoryController::QuotaAllocationTask; | 49 using QuotaAllocationTask = BlobMemoryController::QuotaAllocationTask; |
48 using DiskSpaceFuncPtr = BlobMemoryController::DiskSpaceFuncPtr; | 50 using DiskSpaceFuncPtr = BlobMemoryController::DiskSpaceFuncPtr; |
49 | 51 |
50 // CrOS: | 52 // CrOS: |
51 // * Ram - 20% | 53 // * Ram - 20% |
52 // * Disk - 50% | 54 // * Disk - 50% |
53 // Note: The disk is the user partition, so the operating system can still | 55 // Note: The disk is the user partition, so the operating system can still |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 | 500 |
499 BlobMemoryController::BlobMemoryController( | 501 BlobMemoryController::BlobMemoryController( |
500 const base::FilePath& storage_directory, | 502 const base::FilePath& storage_directory, |
501 scoped_refptr<base::TaskRunner> file_runner) | 503 scoped_refptr<base::TaskRunner> file_runner) |
502 : file_paging_enabled_(file_runner.get() != nullptr), | 504 : file_paging_enabled_(file_runner.get() != nullptr), |
503 blob_storage_dir_(storage_directory), | 505 blob_storage_dir_(storage_directory), |
504 file_runner_(std::move(file_runner)), | 506 file_runner_(std::move(file_runner)), |
505 disk_space_function_(&base::SysInfo::AmountOfFreeDiskSpace), | 507 disk_space_function_(&base::SysInfo::AmountOfFreeDiskSpace), |
506 populated_memory_items_( | 508 populated_memory_items_( |
507 base::MRUCache<uint64_t, ShareableBlobDataItem*>::NO_AUTO_EVICT), | 509 base::MRUCache<uint64_t, ShareableBlobDataItem*>::NO_AUTO_EVICT), |
| 510 memory_pressure_listener_( |
| 511 base::Bind(&BlobMemoryController::OnMemoryPressure, |
| 512 base::Unretained(this))), |
508 weak_factory_(this) {} | 513 weak_factory_(this) {} |
509 | 514 |
510 BlobMemoryController::~BlobMemoryController() {} | 515 BlobMemoryController::~BlobMemoryController() {} |
511 | 516 |
512 void BlobMemoryController::DisableFilePaging(base::File::Error reason) { | 517 void BlobMemoryController::DisableFilePaging(base::File::Error reason) { |
513 UMA_HISTOGRAM_ENUMERATION("Storage.Blob.PagingDisabled", -reason, | 518 UMA_HISTOGRAM_ENUMERATION("Storage.Blob.PagingDisabled", -reason, |
514 -File::FILE_ERROR_MAX); | 519 -File::FILE_ERROR_MAX); |
515 DLOG(ERROR) << "Blob storage paging disabled, reason: " << reason; | 520 DLOG(ERROR) << "Blob storage paging disabled, reason: " << reason; |
516 file_paging_enabled_ = false; | 521 file_paging_enabled_ = false; |
517 in_flight_memory_used_ = 0; | 522 in_flight_memory_used_ = 0; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 // more paging for any more pending blobs. | 602 // more paging for any more pending blobs. |
598 if (!pending_memory_quota_tasks_.empty()) { | 603 if (!pending_memory_quota_tasks_.empty()) { |
599 return AppendMemoryTask(total_bytes_needed, | 604 return AppendMemoryTask(total_bytes_needed, |
600 std::move(unreserved_memory_items), done_callback); | 605 std::move(unreserved_memory_items), done_callback); |
601 } | 606 } |
602 | 607 |
603 // Store right away if we can. | 608 // Store right away if we can. |
604 if (total_bytes_needed <= GetAvailableMemoryForBlobs()) { | 609 if (total_bytes_needed <= GetAvailableMemoryForBlobs()) { |
605 GrantMemoryAllocations(&unreserved_memory_items, | 610 GrantMemoryAllocations(&unreserved_memory_items, |
606 static_cast<size_t>(total_bytes_needed)); | 611 static_cast<size_t>(total_bytes_needed)); |
607 MaybeScheduleEvictionUntilSystemHealthy(); | 612 MaybeScheduleEvictionUntilSystemHealthy( |
| 613 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE); |
608 done_callback.Run(true); | 614 done_callback.Run(true); |
609 return base::WeakPtr<QuotaAllocationTask>(); | 615 return base::WeakPtr<QuotaAllocationTask>(); |
610 } | 616 } |
611 | 617 |
612 // Size is larger than available memory. | 618 // Size is larger than available memory. |
613 DCHECK(pending_memory_quota_tasks_.empty()); | 619 DCHECK(pending_memory_quota_tasks_.empty()); |
614 DCHECK_EQ(0u, pending_memory_quota_total_size_); | 620 DCHECK_EQ(0u, pending_memory_quota_total_size_); |
615 | 621 |
616 auto weak_ptr = AppendMemoryTask( | 622 auto weak_ptr = AppendMemoryTask( |
617 total_bytes_needed, std::move(unreserved_memory_items), done_callback); | 623 total_bytes_needed, std::move(unreserved_memory_items), done_callback); |
618 MaybeScheduleEvictionUntilSystemHealthy(); | 624 MaybeScheduleEvictionUntilSystemHealthy( |
| 625 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE); |
619 return weak_ptr; | 626 return weak_ptr; |
620 } | 627 } |
621 | 628 |
622 base::WeakPtr<QuotaAllocationTask> BlobMemoryController::ReserveFileQuota( | 629 base::WeakPtr<QuotaAllocationTask> BlobMemoryController::ReserveFileQuota( |
623 std::vector<scoped_refptr<ShareableBlobDataItem>> unreserved_file_items, | 630 std::vector<scoped_refptr<ShareableBlobDataItem>> unreserved_file_items, |
624 const FileQuotaRequestCallback& done_callback) { | 631 const FileQuotaRequestCallback& done_callback) { |
625 pending_file_quota_tasks_.push_back(base::MakeUnique<FileQuotaAllocationTask>( | 632 pending_file_quota_tasks_.push_back(base::MakeUnique<FileQuotaAllocationTask>( |
626 this, disk_space_function_, std::move(unreserved_file_items), | 633 this, disk_space_function_, std::move(unreserved_file_items), |
627 done_callback)); | 634 done_callback)); |
628 pending_file_quota_tasks_.back()->set_my_list_position( | 635 pending_file_quota_tasks_.back()->set_my_list_position( |
(...skipping 13 matching lines...) Expand all Loading... |
642 items_paging_to_file_.end()) { | 649 items_paging_to_file_.end()) { |
643 return; | 650 return; |
644 } | 651 } |
645 auto iterator = populated_memory_items_.Get(item->item_id()); | 652 auto iterator = populated_memory_items_.Get(item->item_id()); |
646 if (iterator == populated_memory_items_.end()) { | 653 if (iterator == populated_memory_items_.end()) { |
647 populated_memory_items_bytes_ += | 654 populated_memory_items_bytes_ += |
648 static_cast<size_t>(item->item()->length()); | 655 static_cast<size_t>(item->item()->length()); |
649 populated_memory_items_.Put(item->item_id(), item.get()); | 656 populated_memory_items_.Put(item->item_id(), item.get()); |
650 } | 657 } |
651 } | 658 } |
652 MaybeScheduleEvictionUntilSystemHealthy(); | 659 MaybeScheduleEvictionUntilSystemHealthy( |
| 660 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE); |
653 } | 661 } |
654 | 662 |
655 void BlobMemoryController::CalculateBlobStorageLimits() { | 663 void BlobMemoryController::CalculateBlobStorageLimits() { |
656 if (file_runner_) { | 664 if (file_runner_) { |
657 PostTaskAndReplyWithResult( | 665 PostTaskAndReplyWithResult( |
658 file_runner_.get(), FROM_HERE, | 666 file_runner_.get(), FROM_HERE, |
659 base::Bind(&CalculateBlobStorageLimitsImpl, blob_storage_dir_, true), | 667 base::Bind(&CalculateBlobStorageLimitsImpl, blob_storage_dir_, true), |
660 base::Bind(&BlobMemoryController::OnStorageLimitsCalculated, | 668 base::Bind(&BlobMemoryController::OnStorageLimitsCalculated, |
661 weak_factory_.GetWeakPtr())); | 669 weak_factory_.GetWeakPtr())); |
662 } else { | 670 } else { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 std::unique_ptr<MemoryQuotaAllocationTask> memory_task = | 772 std::unique_ptr<MemoryQuotaAllocationTask> memory_task = |
765 std::move(pending_memory_quota_tasks_.front()); | 773 std::move(pending_memory_quota_tasks_.front()); |
766 pending_memory_quota_tasks_.pop_front(); | 774 pending_memory_quota_tasks_.pop_front(); |
767 pending_memory_quota_total_size_ -= memory_task->allocation_size(); | 775 pending_memory_quota_total_size_ -= memory_task->allocation_size(); |
768 memory_task->RunDoneCallback(true); | 776 memory_task->RunDoneCallback(true); |
769 } | 777 } |
770 RecordTracingCounters(); | 778 RecordTracingCounters(); |
771 } | 779 } |
772 | 780 |
773 size_t BlobMemoryController::CollectItemsForEviction( | 781 size_t BlobMemoryController::CollectItemsForEviction( |
774 std::vector<scoped_refptr<ShareableBlobDataItem>>* output) { | 782 std::vector<scoped_refptr<ShareableBlobDataItem>>* output, |
| 783 uint64_t min_page_file_size) { |
775 base::CheckedNumeric<size_t> total_items_size = 0; | 784 base::CheckedNumeric<size_t> total_items_size = 0; |
776 // Process the recent item list and remove items until we have at least a | 785 // Process the recent item list and remove items until we have at least a |
777 // minimum file size or we're at the end of our items to page to disk. | 786 // minimum file size or we're at the end of our items to page to disk. |
778 while (total_items_size.ValueOrDie() < limits_.min_page_file_size && | 787 while (total_items_size.ValueOrDie() < min_page_file_size && |
779 !populated_memory_items_.empty()) { | 788 !populated_memory_items_.empty()) { |
780 auto iterator = --populated_memory_items_.end(); | 789 auto iterator = --populated_memory_items_.end(); |
781 ShareableBlobDataItem* item = iterator->second; | 790 ShareableBlobDataItem* item = iterator->second; |
782 DCHECK_EQ(item->item()->type(), DataElement::TYPE_BYTES); | 791 DCHECK_EQ(item->item()->type(), DataElement::TYPE_BYTES); |
783 populated_memory_items_.Erase(iterator); | 792 populated_memory_items_.Erase(iterator); |
784 size_t size = base::checked_cast<size_t>(item->item()->length()); | 793 size_t size = base::checked_cast<size_t>(item->item()->length()); |
785 populated_memory_items_bytes_ -= size; | 794 populated_memory_items_bytes_ -= size; |
786 total_items_size += size; | 795 total_items_size += size; |
787 output->push_back(make_scoped_refptr(item)); | 796 output->push_back(make_scoped_refptr(item)); |
788 } | 797 } |
789 return total_items_size.ValueOrDie(); | 798 return total_items_size.ValueOrDie(); |
790 } | 799 } |
791 | 800 |
792 void BlobMemoryController::MaybeScheduleEvictionUntilSystemHealthy() { | 801 void BlobMemoryController::MaybeScheduleEvictionUntilSystemHealthy( |
| 802 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { |
793 // Don't do eviction when others are happening, as we don't change our | 803 // Don't do eviction when others are happening, as we don't change our |
794 // pending_memory_quota_total_size_ value until after the paging files have | 804 // pending_memory_quota_total_size_ value until after the paging files have |
795 // been written. | 805 // been written. |
796 if (pending_evictions_ != 0 || !file_paging_enabled_) | 806 if (pending_evictions_ != 0 || !file_paging_enabled_) |
797 return; | 807 return; |
798 | 808 |
799 uint64_t total_memory_usage = | 809 uint64_t total_memory_usage = |
800 static_cast<uint64_t>(pending_memory_quota_total_size_) + | 810 static_cast<uint64_t>(pending_memory_quota_total_size_) + |
801 blob_memory_used_; | 811 blob_memory_used_; |
802 | 812 |
| 813 size_t in_memory_limit = limits_.memory_limit_before_paging(); |
| 814 uint64_t min_page_file_size = limits_.min_page_file_size; |
| 815 if (memory_pressure_level != |
| 816 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) { |
| 817 in_memory_limit = 0; |
| 818 // Use lower page file size to reduce using more memory for writing under |
| 819 // pressure. |
| 820 min_page_file_size = limits_.max_blob_in_memory_space * |
| 821 limits_.max_blob_in_memory_space_under_pressure_ratio; |
| 822 } |
| 823 |
803 // We try to page items to disk until our current system size + requested | 824 // We try to page items to disk until our current system size + requested |
804 // memory is below our size limit. | 825 // memory is below our size limit. |
805 // Size limit is a lower |memory_limit_before_paging()| if we have disk space. | 826 // Size limit is a lower |memory_limit_before_paging()| if we have disk space. |
806 while (total_memory_usage > limits_.effective_max_disk_space || | 827 while (total_memory_usage > limits_.effective_max_disk_space || |
807 (disk_used_ < limits_.effective_max_disk_space && | 828 (disk_used_ < limits_.effective_max_disk_space && |
808 total_memory_usage > limits_.memory_limit_before_paging())) { | 829 total_memory_usage > in_memory_limit)) { |
| 830 const char* reason = nullptr; |
| 831 if (memory_pressure_level != |
| 832 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) { |
| 833 reason = "OnMemoryPressure"; |
| 834 } else if (total_memory_usage > limits_.effective_max_disk_space) { |
| 835 reason = "SizeExceededMaxDiskSpace"; |
| 836 } else { |
| 837 reason = "SizeExceededInMemoryLimit"; |
| 838 } |
| 839 |
809 // We only page when we have enough items to fill a whole page file. | 840 // We only page when we have enough items to fill a whole page file. |
810 if (populated_memory_items_bytes_ < limits_.min_page_file_size) | 841 if (populated_memory_items_bytes_ < min_page_file_size) |
811 break; | 842 break; |
812 DCHECK_LE(limits_.min_page_file_size, | 843 DCHECK_LE(min_page_file_size, static_cast<uint64_t>(blob_memory_used_)); |
813 static_cast<uint64_t>(blob_memory_used_)); | |
814 | 844 |
815 std::vector<scoped_refptr<ShareableBlobDataItem>> items_to_swap; | 845 std::vector<scoped_refptr<ShareableBlobDataItem>> items_to_swap; |
816 size_t total_items_size = CollectItemsForEviction(&items_to_swap); | 846 |
| 847 size_t total_items_size = |
| 848 CollectItemsForEviction(&items_to_swap, min_page_file_size); |
817 if (total_items_size == 0) | 849 if (total_items_size == 0) |
818 break; | 850 break; |
819 | 851 |
820 std::vector<DataElement*> items_for_paging; | 852 std::vector<DataElement*> items_for_paging; |
821 for (auto& shared_blob_item : items_to_swap) { | 853 for (auto& shared_blob_item : items_to_swap) { |
822 items_paging_to_file_.insert(shared_blob_item->item_id()); | 854 items_paging_to_file_.insert(shared_blob_item->item_id()); |
823 items_for_paging.push_back(shared_blob_item->item()->data_element_ptr()); | 855 items_for_paging.push_back(shared_blob_item->item()->data_element_ptr()); |
824 } | 856 } |
825 | 857 |
826 // Update our bookkeeping. | 858 // Update our bookkeeping. |
(...skipping 15 matching lines...) Expand all Loading... |
842 | 874 |
843 // Post the file writing task. | 875 // Post the file writing task. |
844 base::PostTaskAndReplyWithResult( | 876 base::PostTaskAndReplyWithResult( |
845 file_runner_.get(), FROM_HERE, | 877 file_runner_.get(), FROM_HERE, |
846 base::Bind(&CreateFileAndWriteItems, blob_storage_dir_, | 878 base::Bind(&CreateFileAndWriteItems, blob_storage_dir_, |
847 disk_space_function_, base::Passed(&page_file_path), | 879 disk_space_function_, base::Passed(&page_file_path), |
848 file_runner_, base::Passed(&items_for_paging), | 880 file_runner_, base::Passed(&items_for_paging), |
849 total_items_size), | 881 total_items_size), |
850 base::Bind(&BlobMemoryController::OnEvictionComplete, | 882 base::Bind(&BlobMemoryController::OnEvictionComplete, |
851 weak_factory_.GetWeakPtr(), base::Passed(&file_reference), | 883 weak_factory_.GetWeakPtr(), base::Passed(&file_reference), |
852 base::Passed(&items_to_swap), total_items_size)); | 884 base::Passed(&items_to_swap), total_items_size, reason, |
| 885 total_memory_usage)); |
| 886 |
| 887 last_eviction_time_ = base::TimeTicks::Now(); |
853 } | 888 } |
854 RecordTracingCounters(); | 889 RecordTracingCounters(); |
855 } | 890 } |
856 | 891 |
857 void BlobMemoryController::OnEvictionComplete( | 892 void BlobMemoryController::OnEvictionComplete( |
858 scoped_refptr<ShareableFileReference> file_reference, | 893 scoped_refptr<ShareableFileReference> file_reference, |
859 std::vector<scoped_refptr<ShareableBlobDataItem>> items, | 894 std::vector<scoped_refptr<ShareableBlobDataItem>> items, |
860 size_t total_items_size, | 895 size_t total_items_size, |
| 896 const char* evict_reason, |
| 897 size_t memory_usage_before_eviction, |
861 std::pair<FileCreationInfo, int64_t /* avail_disk */> result) { | 898 std::pair<FileCreationInfo, int64_t /* avail_disk */> result) { |
862 if (!file_paging_enabled_) | 899 if (!file_paging_enabled_) |
863 return; | 900 return; |
864 | 901 |
865 FileCreationInfo& file_info = std::get<0>(result); | 902 FileCreationInfo& file_info = std::get<0>(result); |
866 int64_t avail_disk_space = std::get<1>(result); | 903 int64_t avail_disk_space = std::get<1>(result); |
867 | 904 |
868 if (file_info.error != File::FILE_OK) { | 905 if (file_info.error != File::FILE_OK) { |
869 DisableFilePaging(file_info.error); | 906 DisableFilePaging(file_info.error); |
870 return; | 907 return; |
(...skipping 15 matching lines...) Expand all Loading... |
886 file_reference->path(), offset, shareable_item->item()->length(), | 923 file_reference->path(), offset, shareable_item->item()->length(), |
887 file_info.last_modified); | 924 file_info.last_modified); |
888 DCHECK(shareable_item->memory_allocation_); | 925 DCHECK(shareable_item->memory_allocation_); |
889 shareable_item->set_memory_allocation(nullptr); | 926 shareable_item->set_memory_allocation(nullptr); |
890 shareable_item->set_item(new_item); | 927 shareable_item->set_item(new_item); |
891 items_paging_to_file_.erase(shareable_item->item_id()); | 928 items_paging_to_file_.erase(shareable_item->item_id()); |
892 offset += shareable_item->item()->length(); | 929 offset += shareable_item->item()->length(); |
893 } | 930 } |
894 in_flight_memory_used_ -= total_items_size; | 931 in_flight_memory_used_ -= total_items_size; |
895 | 932 |
| 933 // Record change in memory usage at the last eviction reply. |
| 934 size_t total_usage = blob_memory_used_ + pending_memory_quota_total_size_; |
| 935 if (!pending_evictions_ && memory_usage_before_eviction >= total_usage) { |
| 936 std::string full_histogram_name = |
| 937 std::string("Storage.Blob.SizeEvictedToDiskInKB.") + evict_reason; |
| 938 base::UmaHistogramCounts100000( |
| 939 full_histogram_name, |
| 940 (memory_usage_before_eviction - total_usage) / 1024); |
| 941 } |
| 942 |
896 // We want callback on blobs up to the amount we've freed. | 943 // We want callback on blobs up to the amount we've freed. |
897 MaybeGrantPendingMemoryRequests(); | 944 MaybeGrantPendingMemoryRequests(); |
898 | 945 |
899 // If we still have more blobs waiting and we're not waiting on more paging | 946 // If we still have more blobs waiting and we're not waiting on more paging |
900 // operations, schedule more. | 947 // operations, schedule more. |
901 MaybeScheduleEvictionUntilSystemHealthy(); | 948 MaybeScheduleEvictionUntilSystemHealthy( |
| 949 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE); |
| 950 } |
| 951 |
| 952 void BlobMemoryController::OnMemoryPressure( |
| 953 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { |
| 954 auto time_from_last_evicion = base::TimeTicks::Now() - last_eviction_time_; |
| 955 if (time_from_last_evicion.InSeconds() < kMinSecondsForPressureEvictions) |
| 956 return; |
| 957 |
| 958 MaybeScheduleEvictionUntilSystemHealthy(memory_pressure_level); |
902 } | 959 } |
903 | 960 |
904 FilePath BlobMemoryController::GenerateNextPageFileName() { | 961 FilePath BlobMemoryController::GenerateNextPageFileName() { |
905 std::string file_name = base::Uint64ToString(current_file_num_++); | 962 std::string file_name = base::Uint64ToString(current_file_num_++); |
906 return blob_storage_dir_.Append(FilePath::FromUTF8Unsafe(file_name)); | 963 return blob_storage_dir_.Append(FilePath::FromUTF8Unsafe(file_name)); |
907 } | 964 } |
908 | 965 |
909 void BlobMemoryController::RecordTracingCounters() const { | 966 void BlobMemoryController::RecordTracingCounters() const { |
910 TRACE_COUNTER2("Blob", "MemoryUsage", "TotalStorage", blob_memory_used_, | 967 TRACE_COUNTER2("Blob", "MemoryUsage", "TotalStorage", blob_memory_used_, |
911 "InFlightToDisk", in_flight_memory_used_); | 968 "InFlightToDisk", in_flight_memory_used_); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 MaybeGrantPendingMemoryRequests(); | 1034 MaybeGrantPendingMemoryRequests(); |
978 } | 1035 } |
979 | 1036 |
980 void BlobMemoryController::OnBlobFileDelete(uint64_t size, | 1037 void BlobMemoryController::OnBlobFileDelete(uint64_t size, |
981 const FilePath& path) { | 1038 const FilePath& path) { |
982 DCHECK_LE(size, disk_used_); | 1039 DCHECK_LE(size, disk_used_); |
983 disk_used_ -= size; | 1040 disk_used_ -= size; |
984 } | 1041 } |
985 | 1042 |
986 } // namespace storage | 1043 } // namespace storage |
OLD | NEW |