| 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 |