New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 640698 link

Starred by 2 users

Issue metadata

Status: Verified
Owner:
Closed: Sep 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 2
Type: Feature

Blocking:
issue 634696



Sign in to add a comment

DOMStorageArea::SetItem duplicates strings

Project Member Reported by dskiba@chromium.org, Aug 24 2016

Issue description

I'm working on reducing amount of duplicate memory in Clank, and noticed that DOMStorageArea::SetItem() intentionally creates duplicates when it populates commit_batch_ map.

After visiting yahoo.com (and scrolling down couple of pages) I observed that there were 2.8 MiB of duplicate strings (dom_storage / commit_batch value was 1.4 MiB).

As I understand, commit_batch_ is eventually flushed and cleared after ComputeCommitDelay() timeout. And it looks like for 1 MiB payload commit delay is "1 hour * (1 MiB / 10 MiB)", i.e. 6 minutes. For 2 MiB that would be 12 minutes. So the more data website pushes to the local storage, the more duplication we have, and the longer it exists.

One solution I can think of is to only store keys in commit_batch_ map, and populate it with values from map_ in PostCommitTask(), just before submitting it.
 

Comment 1 by dskiba@chromium.org, Aug 24 2016

Blocking: 634696

Comment 2 by jsb...@chromium.org, Aug 29 2016

Labels: Type-Feature
Status: Available (was: Untriaged)
Hrm... a problem with pulling values out of map_ is that the values may have mutated. Currently commit batch guarantees that what's written out is a snapshot of state at some point in time. A scenario would be a page writing A=1, B=1, A=2, B=2, etc. So A is always >= B for any point in time. If we create a commit batch after A=1 and it runs before subsequent changes, then create a commit batch commit again after B=1 but it is delayed we're in trouble: the commit batch would contain the key B but we might read B=2. So the database holds A=1 B=2 which violates the constraint.

Another idea: we could change map_ and commit_batch_ to hold values which are refcounted wrappers around strings.
Hmm, don't quite understand.

So we have sequence [A=1, B=1, A=2, B=2]. We create commit batch with keys {A, B}, and depending on when we actually commit we can write any of {A=1, B=1}, {A=2, B=1}, {A=2, B=2}?

But doesn't this already happen in the current implementation? Depending on where we were in the sequence when commit happened we can write any of {A=1, B=1}, {B=1, A=2} and {A=2, B=2}, since we keep updating commit batch until it's written.

Oops, you're right - we do keep updating the same commit batch. Sorry, hadn't paged everything into my head.

Yeah, that should be safe then. Change to DOMStorageArea::PostCommitTask and DOMStorageArea::Shutdown should be easy. Let me spin that up...
Owner: jsb...@chromium.org
Status: Started (was: Available)
Project Member

Comment 7 by bugdroid1@chromium.org, Sep 6 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/8f224809c2603590ed31259f3d2f0e69494ee417

commit 8f224809c2603590ed31259f3d2f0e69494ee417
Author: jsbell <jsbell@chromium.org>
Date: Tue Sep 06 17:44:53 2016

DOM Storage: Populate commit batch values lazily to avoid memory bloat

DOM Storage (a.k.a. localStorage and sessionStorage) flushes changes
to disks on a timer. It previously held updated keys/values in both an
in-memory map and a "commit batch" of pending updates to write. For
large values (which are common) this duplicated memory until the timer
fired.

To avoid this, keep only the keys in the commit batch until just
before we toss the batch over to the commit thread, and at that point
grab the values from the in-memory map.

BUG= 640698 
R=michaeln@chromium.org,dskiba@chromium.org

Review-Url: https://codereview.chromium.org/2309523002
Cr-Commit-Position: refs/heads/master@{#416652}

[modify] https://crrev.com/8f224809c2603590ed31259f3d2f0e69494ee417/content/browser/dom_storage/dom_storage_area.cc
[modify] https://crrev.com/8f224809c2603590ed31259f3d2f0e69494ee417/content/browser/dom_storage/dom_storage_area.h

Status: Fixed (was: Started)
Thanks for the suggestion, dskiba@ !

Can you verify the expected memory savings?
Thanks jsbell@ for fixing this!

I expect to see a change in the memory dashboard, but it'll probably take some time to show up. I'll post here once I see it.
OK, so we can see a nice improvements here: https://chromeperf.appspot.com/report?sid=c2392b4b078573ec742c1041bab227185dbb660d7fb24753b83fd6ef4d95a4aa

where dom_storage:effective_size_avg dropped by 813 KiB (1717890 -> 884594).

Trace files before/after the drop show that dom_storage/commit_batch dropped from 824.0 KiB to 10.3 KiB.
huzzah!
Status: Verified (was: Fixed)

Sign in to add a comment