Closed Bug 1738290 Opened 4 years ago Closed 2 years ago

Firefox reserves all RAM on a certain page until system hangs

Categories

(Core :: Graphics, defect)

Firefox 93
defect

Tracking

()

RESOLVED INACTIVE

People

(Reporter: debus, Unassigned)

References

Details

Attachments

(1 file)

90.31 KB, application/octet-stream
Details

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0

Steps to reproduce:

System

  • Tested on OpenSUSE TW and Fedora 34 with a 32 GB respectively a 16 GB RAM system
  • Also used a fresh FF profile (/usr/bin/firefox -p --> create new profile)

Open any newspaper of the 'Deutsche digitale Bibliothek' such as [1]

[1] https://www.deutsche-digitale-bibliothek.de/newspaper/item/M7PREGSEDZHGT2ULWUF63OV3DGCKMUG7

You may zoom in and out a little bit and then just wait.

Actual results:

Firefox keeps reserving RAM until the swap file is completely filled and the system starts to hang.

Expected results:

Firefox does not use too much RAM such as Chromium 94, which works fine.

Summary: Firefox reserves all RAM on a certain page → Firefox reserves all RAM on a certain page until system hangs

The Bugbug bot thinks this bug should belong to the 'Core::Performance' component, and is moving the bug to that component. Please revert this change in case you think the bot is wrong.

Component: Untriaged → Performance
Product: Firefox → Core

I can't reproduce this using Nightly / Fedora 34.

https://www.deutsche-digitale-bibliothek.de/newspaper/item/M7PREGSEDZHGT2ULWUF63OV3DGCKMUG7 uses very little memory, at least when comparing to most websites.
The child process takes 80-100MB. Renderer process in Chrome takes 100-120MB

debug, could you perhaps 'measure and save' in about:memory page and upload the report here?

Flags: needinfo?(debus)

To harden my system against this memory leak I got the following strange behavior:
I was looking for a simple way to limit memory consumption by a user and so I put a limit into /etc/security/limits.conf
mt hard as 20000000
the result was that the browser crashed because of not enough memory, but not my server. (The expected result! ++)
When I repeated the invocation of the page with zooming in and out, to reproduce it, nothing happened.
Later I removed the virtual memory limit again, because with it, google-chrome was not running at all.

Now I will try to 'measure and save' ...

Ok, I did manage to reproduce this on Windows 10. Linux has always been fine.

Denis, I think you might have a bit more reasonable Windows machine to take a look at this.

Flags: needinfo?(dpalmeiro)

Is this a regression?

Component: Performance → Graphics

I tried leaving this website open for a few hours after interacting with the newspaper on 2 different windows machines but unfortunately I couldn't witness any increase in memory.

Flags: needinfo?(dpalmeiro)
Attached file (a) memory-report.json

could you perhaps 'measure and save' in about:memory page and upload the report here?

I could reproduce it with Firefox 94.0-18.1 from the mozilla repo of openSUSE (obs://build.opensuse.org/mozilla) and captured the memory report short before the computer started freezing.

Zooming in/out or moving widely the mouse pointer over the newspaper did not have the desired effect for me any longer.

I found however, that clicking very fast with the left mouse button on the virtual newspaper let me trigger the continuous memory allocation and reproduce the bug easily on Linux. (Though I clicked around ~10-20 seconds and observed the allocation in htop).

Flags: needinfo?(debus)

Zooming in/out or moving widely the mouse pointer over the newspaper did not have the desired effect for me any longer.

With that I mean the memory allocation had indeed risen by many GB (up to ~30-50% of total memory) but was always freed early enough to not cause any hangs.

As I wrote in a mail to Olli P. , I found out, that when switching to an other tab, the memory was released. So 'measure and save' in about:memory page returned only the situation with released memory. So probably opening two windows and keeping open the page which uses all the memory may give more details. My system with 32GB of Ram has no swap partition, so out of memory is more a problem for the stability. But I have to admit, that Firefox was the first program to crash my server, running now for a year or so.

So probably opening two windows and keeping open the page which uses all the memory may give more details.

That's exactly what I did in comment 8. I think these numbers

36,393.47 MB ── shmem-mapped
     0.00 MB ── system-heap-allocated
           1 ── unresolved-ipc-responses
40,571.96 MB ── vsize
     0.00 MB ── wasm-runtime

End of Main Process (pid 5599)

are pretty outstanding in this report.

The severity field is not set for this bug.
:jimm, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(jmathies)
Blocks: gfx-triage
Severity: -- → S4
Flags: needinfo?(jmathies)

I reproduced this on macOS.
I suspect a lot of canvas's are being created or something like that.
Here's a stack from Instruments:

39.63 s   85.7%	1.00 ms	 	   mozilla::dom::CanvasRenderingContext2D::DrawImage(mozilla::dom::HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap const&, double, double, double, double, double, double, double, double, unsigned char, mozilla::ErrorResult&)
27.70 s   59.9%	1.00 ms	 	    mozilla::dom::CanvasRenderingContext2D::EnsureTarget(mozilla::gfx::RectTyped<mozilla::gfx::UnknownUnits, float> const*, bool)
27.63 s   59.7%	0 s	 	     mozilla::gfx::DrawTargetSkia::ClearRect(mozilla::gfx::RectTyped<mozilla::gfx::UnknownUnits, float> const&)
27.62 s   59.7%	1.00 ms	 	      SkCanvas::drawColor(unsigned int, SkBlendMode)
27.62 s   59.7%	1.00 ms	 	       SkCanvas::drawPaint(SkPaint const&)
27.62 s   59.7%	0 s	 	        SkCanvas::internalDrawPaint(SkPaint const&)
27.62 s   59.7%	0 s	 	         SkBitmapDevice::drawPaint(SkPaint const&)
27.62 s   59.7%	1.00 ms	 	          SkDraw::drawPaint(SkPaint const&) const
27.62 s   59.7%	8.04 s	 	           avx::rect_memset32(unsigned int*, unsigned int, int, unsigned long, int)
19.43 s   42.0%	0 s	 	            user_trap
14.60 s   31.5%	791.00 ms	 	             0xffffff80003a7a70
5.44 s   11.7%	412.00 ms	 	              vm_fault_enter
Thread 1 "Web Content" hit Breakpoint 1, __GI___mmap64 (addr=0x0, len=34791424, prot=3, flags=1, fd=44, offset=0) at ../sysdeps/unix/sysv/linux/mmap64.c:48
48      ../sysdeps/unix/sysv/linux/mmap64.c: No such file or directory.
(gdb) bt
#0  __GI___mmap64 (addr=0x0, len=34791424, prot=3, flags=1, fd=44, offset=0) at ../sysdeps/unix/sysv/linux/mmap64.c:48
#1  0x00007f577d1d048c in base::SharedMemory::Map(unsigned long, void*) (this=0x7f573d191850, bytes=34791424, fixed_address=0x0)
    at /home/gw/code/work/gecko2/ipc/chromium/src/base/shared_memory_posix.cc:505
#2  0x00007f577d23732c in mozilla::ipc::SharedMemoryBasic::Map(unsigned long, void*) (this=0x7f573d191830, nBytes=34791424, fixed_address=0x3)
    at /home/gw/code/work/gecko2/obj-x86_64-pc-linux-gnu/dist/include/mozilla/ipc/SharedMemoryBasic_chromium.h:46
#3  0x00007f577d2615de in mozilla::ipc::CreateSegment(mozilla::ipc::SharedMemory::SharedMemoryType, unsigned long, unsigned long) (aType=<optimized out>, 
    aType@entry=mozilla::ipc::SharedMemory::TYPE_BASIC, aNBytes=34790400, aExtraSize=4) at /home/gw/code/work/gecko2/ipc/glue/Shmem.cpp:77
#4  mozilla::ipc::Shmem::Alloc(mozilla::ipc::Shmem::PrivateIPDLCaller, unsigned long, mozilla::ipc::SharedMemory::SharedMemoryType, bool, bool)
    (aNBytes=34790400, aType=<optimized out>) at /home/gw/code/work/gecko2/ipc/glue/Shmem.cpp:383
#5  0x00007f577d25fed5 in mozilla::ipc::IToplevelProtocol::CreateSharedMemory(unsigned long, mozilla::ipc::SharedMemory::SharedMemoryType, bool, int*)
    (this=0x7f5778715700, aSize=0, aType=(unknown: 0x212e000), aUnsafe=<optimized out>, aId=aId@entry=0x7ffc34bfb5bc)
    at /home/gw/code/work/gecko2/ipc/glue/ProtocolUtils.cpp:705
#6  0x00007f577d260b4d in mozilla::ipc::IProtocol::CreateSharedMemory(unsigned long, mozilla::ipc::SharedMemory::SharedMemoryType, bool, int*)
    (this=<optimized out>, aSize=34791424, aType=(mozilla::ipc::SharedMemory::TYPE_UNKNOWN | unknown: 0x2), aUnsafe=true, aId=0x7ffc34bfb5bc)
    at /home/gw/code/work/gecko2/ipc/glue/ProtocolUtils.cpp:316
#7  mozilla::ipc::IProtocol::AllocUnsafeShmem(unsigned long, mozilla::ipc::SharedMemory::SharedMemoryType, mozilla::ipc::Shmem*)
    (this=<optimized out>, aSize=34791424, aType=(mozilla::ipc::SharedMemory::TYPE_UNKNOWN | unknown: 0x2), aOutMem=0x7ffc34bfb620)
    at /home/gw/code/work/gecko2/ipc/glue/ProtocolUtils.cpp:438
#8  0x00007f577d9ee29f in mozilla::layers::ShmemTextureData::Create(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::SurfaceFormat, mozilla::gfx::BackendType, mozilla::layers::LayersBackend, mozilla::layers::TextureFlags, mozilla::layers::TextureAllocationFlags, mozilla::ipc::IShmemAllocator*)
    (aSize=..., aFormat=mozilla::gfx::SurfaceFormat::B8G8R8A8, aMoz2DBackend=mozilla::gfx::BackendType::SKIA, aLayersBackend=<optimized out>, aFlags=<optimized out>, aAllocFlags=mozilla::layers::ALLOC_DEFAULT, aAllocator=0x7f57862e00b0) at /home/gw/code/work/gecko2/gfx/layers/BufferTexture.cpp:518
#9  0x00007f577d9e1d31 in mozilla::layers::BufferTextureData::Create<mozilla::layers::LayersIPCChannel*>(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::SurfaceFormat, mozilla::gfx::BackendType, mozilla::layers::LayersBackend, mozilla::layers::TextureFlags, mozilla::layers::TextureAllocationFlags, mozilla::layers::LayersIPCChannel*)
    (aSize=..., aFormat=<optimized out>, aMoz2DBackend=mozilla::gfx::BackendType::SKIA, aLayersBackend=mozilla::layers::LayersBackend::LAYERS_WR, aFlags=mozilla::layers::TextureFlags::NON_BLOCKING_READ_LOCK, aAllocFlags=mozilla::layers::ALLOC_DEFAULT, aAllocator=0x7f57862e00a8)
    at /home/gw/code/work/gecko2/gfx/layers/BufferTexture.h:110
#10 mozilla::layers::TextureClient::CreateForRawBufferAccess(mozilla::layers::LayersIPCChannel*, mozilla::gfx::SurfaceFormat, mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::BackendType, mozilla::layers::LayersBackend, mozilla::layers::TextureFlags, mozilla::layers::TextureAllocationFlags) (aAllocator=aAllocator@entry=0x7f57862e00a8, aFormat=aFormat@entry=mozilla::gfx::SurfaceFormat::B8G8R8A8, aSize=..., aMoz2DBackend=<optimized out>, aLayersBackend=mozilla::layers::LayersBackend::LAYERS_WR, aTextureFlags=aTextureFlags@entry=mozilla::layers::TextureFlags::NON_BLOCKING_READ_LOCK, aAllocFlags=mozilla::layers::ALLOC_DEFAULT) at /home/gw/code/work/gecko2/gfx/layers/client/TextureClient.cpp:1280
#11 0x00007f577d9e1c74 in mozilla::layers::TextureClient::CreateForDrawing(mozilla::layers::TextureForwarder*, mozilla::gfx::SurfaceFormat, mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::layers::KnowsCompositor*, mozilla::layers::BackendSelector, mozilla::layers::TextureFlags, mozilla::layers::TextureAllocationFlags)
    (aAllocator=<optimized out>, aFormat=aFormat@entry=mozilla::gfx::SurfaceFormat::B8G8R8A8, aSize=..., aKnowsCompositor=aKnowsCompositor@entry=0x7f57862d7838, aSelector=aSelector@entry=mozilla::layers::BackendSelector::Canvas, aTextureFlags=aTextureFlags@entry=mozilla::layers::TextureFlags::NON_BLOCKING_READ_LOCK, aAllocFlags=mozilla::layers::ALLOC_DEFAULT) at /home/gw/code/work/gecko2/gfx/layers/client/TextureClient.cpp:1173
#12 0x00007f577d9e1b34 in mozilla::layers::TextureClient::CreateForDrawing(mozilla::layers::KnowsCompositor*, mozilla::gfx::SurfaceFormat, mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::layers::BackendSelector, mozilla::layers::TextureFlags, mozilla::layers::TextureAllocationFlags)
    (aAllocator=0x7f57862d7838, aFormat=mozilla::gfx::SurfaceFormat::B8G8R8A8, aSize=..., aSelector=(unknown: 0x2c), aTextureFlags=mozilla::layers::TextureFlags::NO_FLAGS, aAllocFlags=mozilla::layers::ALLOC_DEFAULT) at /home/gw/code/work/gecko2/gfx/layers/client/TextureClient.cpp:1140
#13 0x00007f577d9dd444 in mozilla::layers::PersistentBufferProviderShared::Create(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::SurfaceFormat, mozilla::layers::KnowsCompositor*) (aSize=..., aFormat=<optimized out>, aKnowsCompositor=0x7f57862d7838)
    at /home/gw/code/work/gecko2/gfx/layers/PersistentBufferProvider.cpp:138
#14 0x00007f577daf78ec in mozilla::layers::WebRenderLayerManager::CreatePersistentBufferProvider(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::SurfaceFormat) (this=0x7f57787a8200, aSize=..., aFormat=mozilla::gfx::SurfaceFormat::B8G8R8A8)
    at /home/gw/code/work/gecko2/gfx/layers/wr/WebRenderLayerManager.cpp:743
#15 0x00007f577e960e26 in mozilla::dom::CanvasRenderingContext2D::TrySharedTarget(RefPtr<mozilla::gfx::DrawTarget>&, RefPtr<mozilla::layers::PersistentBufferProvider>&) (this=this@entry=0x7f573d1e9300, aOutDT=..., aOutProvider=...) at /home/gw/code/work/gecko2/dom/canvas/CanvasRenderingContext2D.cpp:1465
#16 0x00007f577e960946 in mozilla::dom::CanvasRenderingContext2D::EnsureTarget(mozilla::gfx::RectTyped<mozilla::gfx::UnknownUnits, float> const*, bool)
    (this=this@entry=0x7f573d1e9300, aCoveredRect=<optimized out>, aCoveredRect@entry=0x0, aWillClear=false)
    at /home/gw/code/work/gecko2/dom/canvas/CanvasRenderingContext2D.cpp:1317
#17 0x00007f577e96c1a6 in mozilla::dom::CanvasRenderingContext2D::DrawImage(mozilla::dom::HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap const&, double, double, double, double, double, double, double, double, unsigned char, mozilla::ErrorResult&)
    (this=0x7f573d1e9300, aImage=..., aSx=<optimized out>, aSy=<optimized out>, aSw=<optimized out>, aSh=<optimized out>, aDx=<optimized out>, aDy=<optimized out>, aDw=2400, aDh=3624, aOptional_argc=6 '\006', aError=...) at /home/gw/code/work/gecko2/dom/canvas/CanvasRenderingContext2D.cpp:4489
#18 0x00007f577e377117 in mozilla::dom::CanvasRenderingContext2D_Binding::drawImage(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&)
    (cx_=<optimized out>, obj=..., void_self=0x7f573d1e9300, args=...)
    at /home/gw/code/work/gecko2/obj-x86_64-pc-linux-gnu/dist/include/mozilla/dom/CanvasRenderingContext2D.h:244
#19 0x00007f577e9101d0 in mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) (cx=0x7f5778315100, argc=9, vp=<optimized out>)
    at /home/gw/code/work/gecko2/dom/bindings/BindingUtils.cpp:3306
#20 0x00002faae23d0012 in  ()
#21 0x0000000000000000 in  ()
(gdb) up
#1  0x00007f577d1d048c in base::SharedMemory::Map (this=0x7f573d191850, bytes=34791424, fixed_address=0x0)
    at /home/gw/code/work/gecko2/ipc/chromium/src/base/shared_memory_posix.cc:505
505           mmap(fixed_address, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE),
(gdb) 
Flags: needinfo?(lsalzman)
No longer blocks: gfx-triage
Status: UNCONFIRMED → RESOLVED
Closed: 2 years ago
Flags: needinfo?(lsalzman)
Resolution: --- → INACTIVE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: