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

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 3
Type: Bug

Blocking:
issue 536263


Show other hotlists

Hotlists containing this issue:
Relevant-for-Bootstrap-4


Sign in to add a comment
link

Issue 429375: CSS infinite linear animation w/ alpha transparency leaks memory

Reported by cvreb...@gmail.com, Oct 31 2014

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36

Example URL:
http://jsfiddle.net/cvrhulu/o470t83o/show/

Steps to reproduce the problem:
1. Open http://jsfiddle.net/cvrhulu/o470t83o/show/ (or open http://getbootstrap.com/components/#progress-animated and click the "Toggle animation" button).
2. Leave the browser tab with that webpage open and visible for an extended period.

What is the expected behavior?
Chrome shouldn't leak memory, since the Fiddle contains no significant JavaScript and the JS in the Bootstrap docs is believed to not have any significant memory leaks. And since the leak has been observed even with JavaScript disabled.

What went wrong?
Chrome seems to experience a memory leak, and its memory usage over time increases without bound.

Does it occur on multiple sites: N/A

Is it a problem with a plugin? No 

Did this work before? N/A 

Does this work in other browsers? Yes 

Chrome version: 38.0.2125.111  Channel: stable
OS Version: OS X 10.10.0
Flash Version: Shockwave Flash 15.0 r0

Original Bootstrap issue with some more info: https://github.com/twbs/bootstrap/issues/14409
Other repro URL: http://getbootstrap.com/components/#progress-animated (after clicking the "Toggle animation" button, which was added specifically due to this Chrome memory leak!)

The memory leak has been reported by users on both Mac OS X and Windows 7 Pro.

It was originally observed on http://getbootstrap.com/components/#progress-animated
A Bootstrap user (@ssorallen) reported still observing the memory leak after disabling JavaScript, hence why we believe this is CSS-related.
The same user also reported that removing the animation CSS from the example animated progress bar avoided the memory leak, hence why we believe the leak is related to this animation specifically.

That user further reported that eliminating the alpha transparency from the color stops seemed to avoid the memory leak.
 

Comment 1 by rponnada@chromium.org, Nov 3 2014

Labels: Needs-Feedback M-38
Unable to repro this issue on MACBookpro 10.9.5 using: 38.0.2125.111 with below steps:

1. Opened http://jsfiddle.net/cvrhulu/o470t83o/show/
2. Opened chrome task manager and observed the memory usage for above tab

Left the page visible for 30 min and observed no memory link. 

Could you please re-check this issue on clean profile and confirm the same. If issue is still repro, please provide more steps along with chrome://gpu will help further.

Comment 2 by jean.raj...@gmail.com, Nov 3 2014

The fiddle page doesn't leak on Windows 7 in Chrome.

My issue I think isn't w/ the progress bar, it's with the carousel from Bootstrap.

I have a page opened w/ a carousel in Chrome Version 38.0.2125.111 m and over time it eats up memory (it's currently @ 1 Gb, according to the Chrome Task Manager.  The same page is stable 235 Mb in Firefox.

I hope this helps.

Comment 3 by cvreb...@gmail.com, Nov 4 2014

Well, Ross observed a memory leak even with JavaScript disabled, so that would suggest that there's a non-Carousel-related leak.

(Not saying it isn't possible for the Carousel to have its own additional leaks though.)

Comment 4 by tkent@chromium.org, Nov 6 2014

Labels: Cr-Blink-Animation Performance-Memory

Comment 5 by smokana@chromium.org, Jan 12 2015

Labels: -Type-Compat -OS-Mac -Needs-Feedback -M-38 Type-Bug OS-All M-41
Status: Untriaged
Able to reproduce the issue on Windows and Linux as well, please review attached screenshot. This is a Non Regression issue seen from 26.0.1410.56.

Comment 6 by smokana@chromium.org, Jan 12 2015

429375.JPG
197 KB View Download

Comment 7 by pennymac@google.com, Jan 15 2015

Labels: -M-41 M-42 MovedFrom-41
Moving all non essential bugs to the next Milestone.

Comment 8 by amineer@chromium.org, Mar 3 2015

Labels: -M-42 MovedFrom-42
[AUTO] This issue has already been moved once and is lower than Priority 1,therefore removing mstone.

Comment 9 by samli@chromium.org, Mar 12 2015

Owner: samli@chromium.org

Comment 10 by samli@chromium.org, Mar 12 2015

Labels: -Pri-2 Pri-1 M43 Cr-Blink-Performance
This appears to be quite a severe issue. Looks like high memory & CPU usage. Someone should take a closer look.

Comment 11 by samli@chromium.org, Mar 12 2015

Comment 12 by samli@chromium.org, Mar 12 2015

Labels: -M43
Status: Available

Comment 13 by tkent@chromium.org, Jul 15 2015

Labels: -Cr-Blink-Performance Performance

Comment 14 by tkent@chromium.org, Sep 26 2015

Blocking: chromium:536263

Comment 15 by addyo@chromium.org, Oct 5 2015

Cc: rsch...@chromium.org
@rschoen I was able to repro pretty high CPU usage for this in M47 and it's still causing Bootstrap quite a few performance issues in Chrome. Would a member of your team have time to take a look at this one?

Comment 16 by samli@chromium.org, Dec 30 2015

Owner: ----

Comment 17 by sinspi...@gmail.com, Mar 3 2016

I'm able to reproduce this consistently when having a backface-visibility: hidden applied to the element. See my codepen:

http://codepen.io/sinspiral/pen/eZpOOX

I'm on OSX 10.11.3 and Chrome 48.0.2564.116

Comment 18 by alancutter@chromium.org, May 26 2016

Labels: Update-Monthly

Comment 19 by suzyh@chromium.org, May 26 2016

Labels: -Update-Monthly

Comment 20 by suzyh@chromium.org, May 26 2016

Labels: Update-Monthly

Comment 21 by suzyh@chromium.org, Jun 27 2016

This has been open for a while, so I'm attempting a fresh repro with Chrome unstable (53.0.2774.3) on Linux.

The minimized test case in #11 doesn't seem to be showing any memory leak for me, but I am seeing a gradual increase in memory in http://jsfiddle.net/cvrhulu/o470t83o/show/ from the original report and in the extra report in #17.

Comment 22 by suzyh@chromium.org, Jul 28 2016

Owner: suzyh@chromium.org
Status: Assigned (was: Available)

Comment 23 by suzyh@chromium.org, Aug 11 2016

Cc: suzyh@chromium.org
Owner: haraken@chromium.org
I've investigated this further on Canary using chrome://tracing (following https://chromium.googlesource.com/chromium/src/+/master/components/tracing/docs/memory_infra.md).

One thing I've found which looks curious is in the "Memory per component" graph for the tab, showing a gradual increase in the "malloc" category. According to the above .md file that means "Memory allocated by calls to malloc, or new for most non-Blink objects." Drilling down into that component, most of the memory is in the unhelpfully-named "allocated_objects" > "<unspecified>" section.

I tried "tools/valgrind/valgrind.sh -v out/GnRelease/content_shell http://jsfiddle.net/cvrhulu/o470t83o/show/" (with use_allocator=none in my gn args, as advised by https://chromium.googlesource.com/chromium/src/+/master/docs/linux_debugging.md#Using-valgrind). Nothing stood out to me, but I've also never really done this before.

I'm at a loss for how to investigate this further. Passing over to haraken from the memory team.

haraken, any advice?

Comment 24 by haraken@chromium.org, Aug 11 2016

Cc: haraken@chromium.org primiano@chromium.org dskiba@chromium.org
Owner: tasak@google.com
We need to identify what objects are leaking in malloc, but the information is not (yet) available in the current memory-infra.

tasak@, dskiba@: Should we try the native-stack profiler to identify objects & stack traces leaking in the page?

Comment 25 by dskiba@chromium.org, Aug 11 2016

Yes, definitely, if we saw that malloc increases, the next step to use native heap profiling, as outlined in https://chromium.googlesource.com/chromium/src/+/master/components/tracing/docs/heap_profiler.md

The only catch is that native heap profiler works only on Linux / Android for now.

Comment 26 by suzyh@chromium.org, Aug 12 2016

Cc: vollick@chromium.org loyso@chromium.org tasak@google.com
Components: -Blink>Animation Internals>Compositing
Labels: -Update-Monthly
Owner: weiliangc@chromium.org
I applied the heap profiling instructions from that link (just the basic one, without compiling for native heap profiling) and saw what seems to be a large increases in

cc/trees
LayerTreeHost::UpdateLayers::BuildPropertyTrees

cc/tiles
TileManager::DidFinishRunningTileTasksRequiredForActivation
TileManager::DidFinishRunningTileTasksRequiredForDraw

and nothing significant under third_party/WebKit.

Transferring over to the compositor folks. weiliangc, can you take a look?

Comment 27 by loyso@chromium.org, Aug 12 2016

Cc: ajuma@chromium.org

Comment 28 by vmi...@chromium.org, Sep 27 2016

Cc: weiliangc@chromium.org vmp...@chromium.org
Labels: M-55
Owner: vollick@chromium.org
vollick@ could you please find an owner for the memory leak in LayerTreeHost::UpdateLayers::BuildPropertyTrees in #26?

vnpstr@ could you please take a lok at the possible TileManager memory leak in #26?

Comment 29 by brajkumar@chromium.org, Nov 2 2016

Gentle Ping! Since this is a P1 bug for M55, could any one let us know is there any latest update available for this issue? M55 is already in Beta and mostly we are planning to push the same to stable soon in this month.

Thanks!

Comment 30 by vollick@chromium.org, Nov 2 2016

Owner: ajuma@chromium.org
Ali, could you please look at the build property trees issue?

Comment 31 by ajuma@chromium.org, Nov 3 2016

Owner: vmp...@chromium.org
I followed the native heap profiling instructions to get traces of each of the three pages from above on ToT Linux:
https://drive.google.com/drive/folders/0B5gAVdiWpeDMMGVDWldCOXN1ekE?usp=sharing

1) The original page (http://jsfiddle.net/cvrhulu/o470t83o/show/) is trace_heap1.json.gz (see process 30932)
2) http://dabblet.com/gist/daa0050ca11a2f50e8de from #11 is trace_heap2.json.gz (see process 21050)
3) http://codepen.io/sinspiral/pen/eZpOOX from #17 is trace_heap3.json.gz (see process 16408)

For (1), the main increases are in malloc and skia. For malloc, the entire increase (4.5 MB over 20 seconds) comes from the metadata_fragmentation_caches category, and for skia the entire increase (3.5 MB over 20 seconds) comes from sk_resource_cache. Looking at the stacks, allocation from PropertyTreeBuilder stays consistent at ~5 KB throughout, so there doesn't seem to be a leak there.

For (2) and (3) the only increase that stands out is in malloc (4 MB over 20 seconds) and again it's entirely in metadata_fragmentation_caches. (And allocation from PropertyTreeBuilder stays consistent, ~5 KB on (2) and ~13 KB on (3).)

My understanding is that metadata_fragmentation_caches accounts for memory used by the allocator rather than actual objects allocated (or leaked) by code, could someone confirm?

Passing to vmpstr to triage the sk_resource_cache increase in (1).

Comment 32 by dskiba@chromium.org, Nov 3 2016

I ran for more than an hour on http://jsfiddle.net/cvrhulu/o470t83o/show, sampling with second-long traces several times. So in 80 minutes malloc grew by ~1MiB, and growth came from here:

+992.9 KiB [Thread: CompositorTileWorker1/28018]
+992.9 KiB </system/lib/libc.so>
+992.9 KiB ThreadFunc
+992.9 KiB base::SimpleThread::ThreadMain()
+992.9 KiB content::CategorizedWorkerPool::Run(std::__ndk1::vector<cc::TaskCategory, std::__ndk1::allocator<cc::TaskCategory> > const&, base::ConditionVariable*)
+992.9 KiB content::CategorizedWorkerPool::RunTaskWithLockAcquired(std::__ndk1::vector<cc::TaskCategory, std::__ndk1::allocator<cc::TaskCategory> > const&)
+992.9 KiB content::CategorizedWorkerPool::RunTaskInCategoryWithLockAcquired(cc::TaskCategory)
+992.9 KiB RunOnWorkerThread
+992.9 KiB cc::OneCopyRasterBufferProvider::RasterBufferImpl::Playback(cc::RasterSource const*, gfx::Rect const&, gfx::Rect const&, unsigned long long, gfx::SizeF const&, cc::RasterSource::PlaybackSettings const&)
+992.9 KiB cc::OneCopyRasterBufferProvider::PlaybackAndCopyOnWorkerThread(cc::Resource const*, cc::ResourceProvider::ScopedWriteLockGL*, gpu::SyncToken const&, cc::RasterSource const*, gfx::Rect const&, gfx::Rect const&, gfx::SizeF const&, cc::RasterSource::PlaybackSettings const&, unsigned long long, unsigned long long)
+990.1 KiB cc::OneCopyRasterBufferProvider::PlaybackToStagingBuffer(cc::StagingBuffer*, cc::Resource const*, cc::RasterSource const*, gfx::Rect const&, gfx::Rect const&, gfx::SizeF const&, sk_sp<SkColorSpace>, cc::RasterSource::PlaybackSettings const&, unsigned long long, unsigned long long)
+989.2 KiB cc::RasterBufferProvider::PlaybackToMemory(void*, cc::ResourceFormat, gfx::Size const&, unsigned int, cc::RasterSource const*, gfx::Rect const&, gfx::Rect const&, gfx::SizeF const&, sk_sp<SkColorSpace>, cc::RasterSource::PlaybackSettings const&)
+993.6 KiB cc::RasterSource::PlaybackToCanvas(SkCanvas*, gfx::Rect const&, gfx::Rect const&, gfx::SizeF const&, cc::RasterSource::PlaybackSettings const&) const
+994.6 KiB cc::RasterSource::PlaybackToCanvas(SkCanvas*, cc::RasterSource::PlaybackSettings const&) const
+994.6 KiB cc::RasterSource::RasterCommon(SkCanvas*, SkPicture::AbortCallback*) const
+994.6 KiB cc::DisplayItemList::Raster(SkCanvas*, SkPicture::AbortCallback*) const
+994.9 KiB cc::DrawingDisplayItem::Raster(SkCanvas*, SkPicture::AbortCallback*) const
+994.9 KiB SkCanvas::drawPicture(SkPicture const*, SkMatrix const*, SkPaint const*)
+987.1 KiB SkCanvas::onDrawPicture(SkPicture const*, SkMatrix const*, SkPaint const*)
+987.1 KiB SkBigPicture::playback(SkCanvas*, SkPicture::AbortCallback*) const
+987.1 KiB SkRecordDraw(SkRecord const&, SkCanvas*, SkPicture const* const*, SkDrawable* const*, int, SkBBoxHierarchy const*, SkPicture::AbortCallback*)
+987.1 KiB SkCanvas::onDrawRect(SkRect const&, SkPaint const&)
+987.1 KiB SkBitmapDevice::drawRect(SkDraw const&, SkRect const&, SkPaint const&)
+987.1 KiB SkDraw::drawRect(SkRect const&, SkPaint const&, SkMatrix const*, SkRect const*) const
+987.1 KiB SkBlitter::Choose(SkPixmap const&, SkMatrix const&, SkPaint const&, SkSmallAllocator<3u, 3332u>*, bool)
+987.1 KiB SkShader::createContext(SkShader::ContextRec const&, void*) const
+987.1 KiB SkPictureShader::onCreateContext(SkShader::ContextRec const&, void*) const
+987.1 KiB SkPictureShader::PictureShaderContext::Create(void*, SkPictureShader const&, SkShader::ContextRec const&, sk_sp<SkShader>)
+989.1 KiB SkShader::createContext(SkShader::ContextRec const&, void*) const
+989.1 KiB SkImageShader::onCreateContext(SkShader::ContextRec const&, void*) const
+989.1 KiB SkBitmapProcLegacyShader::MakeContext(SkShader const&, SkShader::TileMode, SkShader::TileMode, SkBitmapProvider const&, SkShader::ContextRec const&, void*)
+989.1 KiB SkBitmapProcInfo::init(SkMatrix const&, SkPaint const&)
+989.1 KiB SkBitmapController::requestBitmap(SkBitmapProvider const&, SkMatrix const&, SkFilterQuality, void*, unsigned int)
+989.3 KiB SkDefaultBitmapController::onRequestBitmap(SkBitmapProvider const&, SkMatrix const&, SkFilterQuality, void*, unsigned int)
+989.3 KiB SkDefaultBitmapControllerState::SkDefaultBitmapControllerState(SkBitmapProvider const&, SkMatrix const&, SkFilterQuality, SkSourceGammaTreatment)
+989.3 KiB SkImageCacherator::lockAsBitmap(SkBitmap*, SkImage const*, SkImage::CachingHint)
+988.0 KiB SkImageCacherator::tryLockAsBitmap(SkBitmap*, SkImage const*, SkImage::CachingHint)
+992.0 KiB SkResourceCache::Add(SkResourceCache::Rec*)
+992.0 KiB SkResourceCache::add(SkResourceCache::Rec*)
+992.0 KiB sk_calloc_throw(unsigned int)

(The buffer at the end was exactly 1 MiB).


The only thing SkResourceCache::add() that can cause an allocation is fHash->add(rec), which is SkTDynamicHash<T>::add(). That function calls maybeGrow(), which is implemented this way:

    void maybeGrow() {
        if (100 * (fCount + fDeleted + 1) > fCapacity * kGrowPercent) {
            this->resize(fCapacity > 0 ? fCapacity * 2 : 4);
        }
    }

What is interesting here is that by repeatedly inserting / removing different keys we can drive fDeleted up, causing this function to double the size.

That is confirmed by looking at the skia/sk_resource_cache entries: the number of bitmap-shader_* entries stays the same, but they are different.

The trace is attached, but be warned that the last point is ~5000 seconds apart from the several first ones, so you'll need to really zoom out (hold S). Click on the first purple one, zoom out, hold Ctrl and click on the last one. Observe the diff.
trace_14-27_15-49.json.gz
1.8 MB Download

Comment 33 by dskiba@chromium.org, Nov 3 2016

Note: the above (#32) was ran on Android.

Comment 34 by dskiba@chromium.org, Nov 4 2016

Components: Internals>Skia
After almost 20 hours SkResourceCache::fHash buffer size grew to 16 MiB.

Comment 35 by vmp...@chromium.org, Nov 7 2016

Owner: reed@google.com
-> reed@ for triage. Seems like it might be a fragmentation issue that keeps growing the cache? From what I recall Skia caches either use discardable memory or they have a hard limit, so I wonder if this will grow some but eventually stop growing. Specifically purgeAsNeeded is called in SkResourceCache::add, which checks some limits and evicts the cache. 

The only place that codesearch seems to find where the non-discardable memory is used is in SkFontMgr, which sets the limit to 32k here: https://cs.chromium.org/chromium/src/third_party/skia/src/ports/SkFontMgr_FontConfigInterface.cpp?sq=package:chromium&rcl=1478435172&l=165

reed@, do you know if there are other places that use non-discardable SkResourceCache?

Comment 36 by reed@google.com, Nov 7 2016

Cc: mtklein@chromium.org

Comment 37 by mtklein@chromium.org, Nov 7 2016

I believe it.  No hash table in Skia ever shrinks its tables.  (They do of course allow elements to be removed.)

I don't think there's any reason we can't have the tables shrink.  If I remember right, it was just a simplification to keep the implementation complexity down.

I'd also like to try getting out of the hash table business altogether, and just try to use std::unordered_map.

Comment 38 by weiliangc@chromium.org, Dec 12 2016

What is the next step? Should this continue to be Pri-1 for M55?

Comment 39 by mtklein@chromium.org, Dec 12 2016

Labels: -Pri-1 Pri-3
I've been looking at updating our hash table code today.

This has been live long enough that I have a hard time believing there's a particular rush for any milestone.

Comment 40 by bugdroid1@chromium.org, Dec 15 2016

Project Member
The following revision refers to this bug:
  https://skia.googlesource.com/skia.git/+/e4bf164225cc6d027566e9bfa0c8492629a6e090

commit e4bf164225cc6d027566e9bfa0c8492629a6e090
Author: Mike Klein <mtklein@chromium.org>
Date: Tue Dec 13 21:26:32 2016

Port SkResourceCache to SkTHashTable

We'd like to fix bugs and make performance improvements to our hash tables.  It's a lot easier if we can focus on one implementation, so I'd like to move users of SkTDynamicHash to SkTHashTable, SkTHashMap, or SkTHashSet.  This is roughly outlined in the attached Skia bug.

In this case, the conversion from SkTDynamicHash to SkTHashTable is pretty trivial.  The main change is that the values stored in the table are no longer assumed to be pointers, so we just need to sprinkle in a couple of * and ->.

SkResourceCache is particularly interesting as the locus of the attached Chromium bug.  Porting this now means SkResourceCache will get any fixes we make as soon as we make them.

BUG= skia:6053 ,chromium:429375

Change-Id: If5dc8d331c62f1d4449fb8f9a7f7e9c746070213
Reviewed-on: https://skia-review.googlesource.com/5984
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>

[modify] https://crrev.com/e4bf164225cc6d027566e9bfa0c8492629a6e090/src/core/SkResourceCache.cpp
[modify] https://crrev.com/e4bf164225cc6d027566e9bfa0c8492629a6e090/src/core/SkResourceCache.h

Comment 41 by bugdroid1@chromium.org, Dec 15 2016

Project Member
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/6e98a82eb3adcc9a1e9ae20e2d26b6dba24f9652

commit 6e98a82eb3adcc9a1e9ae20e2d26b6dba24f9652
Author: skia-deps-roller <skia-deps-roller@chromium.org>
Date: Thu Dec 15 23:37:02 2016

Roll src/third_party/skia/ 344ec42f6..d85dd53e2 (6 commits).

https://skia.googlesource.com/skia.git/+log/344ec42f60fd..d85dd53e288e

$ git log 344ec42f6..d85dd53e2 --date=short --no-merges --format='%ad %ae %s'
2016-12-15 brianosman Shrink the SkImageGenerator API
2016-12-14 stani Exclude complexclip4 GM tests from tile_rt config
2016-12-15 reed speedup dynamicwstream
2016-12-13 mtklein Port SkResourceCache to SkTHashTable
2016-12-15 reed remove unused dynamicwstream.snapshotAsData()
2016-12-15 kjlubick Update Pixel Cs -> NFM26H

BUG=429375

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+/master/autoroll/README.md

If the roll is causing failures, see:
http://www.chromium.org/developers/tree-sheriffs/sheriff-details-chromium#TOC-Failures-due-to-DEPS-rolls

CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel
TBR=msarett@google.com

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

[modify] https://crrev.com/6e98a82eb3adcc9a1e9ae20e2d26b6dba24f9652/DEPS

Comment 42 by benhenry@chromium.org, Apr 25 2017

Labels: -Performance

Comment 43 Deleted

Comment 44 by reed@google.com, Apr 30 2017

Owner: mtklein@chromium.org

Comment 45 by suzyh@chromium.org, Jun 13 2017

Cc: -suzyh@chromium.org

Comment 46 by rsch...@chromium.org, Sep 20 2017

Cc: -rsch...@chromium.org

Sign in to add a comment