Skip to content

Blog

The hundred steps of a heap ceiling

In a Chromium browser a page can ask how much memory its scripts are allowed to hold. The browser has two ways to answer that, and the rounded one puts the number on one of a hundred steps we computed from the engine's own source.

The ARMANOS team6 min

What a page is allowed to ask

Any script in a Chromium browser can read the ceiling on the memory it may hold. Nothing asks the person for permission and nothing on the page shows that it happened.

The value is worth reading for one reason: it does not describe the page. It is arithmetic done on the memory of the machine underneath.

A hundred steps and nothing between

The rounded answer is not rounding by eye but a place in a fixed table. We computed that table with a verbatim copy of the engine source and counted what came out.

Each step keeps three significant digits, and neighbours stand about six percent apart. A number that falls between two of them never reaches the page as it was.

Computed from the engine sourceValue
Steps in the table100
Lowest and highest step10 000 000 and 3 760 000 000
Significant digits kept3
Distance between neighboursabout 6 percent
Smallest and largest gap600 000 and 220 000 000

Why a step hides better than a count

One step is handed to everyone whose real ceiling lands inside it. At the top of the table that band is 220 000 000 bytes wide, and very different machines answer identically.

An exact byte count works the other way round. It is the arithmetic of one machine and one build, it stays the same from visit to visit, and that is the kind of value worth collecting.

77 of the hundred steps lie below a billion bytes. The table is finer at the bottom than at the top, so a small machine is described more closely than a large one.

What the number is made of

The ceiling is two parts added together: a long lived part sized from memory, and a short lived part that comes from the build.

A desktop profile is owed half of its declared memory as the long lived part and a phone profile a quarter. Neither one goes below 256 MB or above 4 GB.

What the app changes and what it leaves

Only the long lived part is replaced, and the number the declared memory calls for takes its place. The short lived part is carried over as it is: it belongs to the build, and writing it by hand would make a fresh tell out of nothing.

When the declared memory already agrees with the machine underneath, the value is not touched at all.

  1. 1

    Declared memory sets the long part

    Half of it on a desktop profile and a quarter on a phone.

  2. 2

    The short part is carried over

    It comes from the build and stays as it was.

  3. 3

    The shape of the answer is kept

    A step stays a step and an exact count stays exact.

A reading on the built engine

The acceptance run reads this value on a built engine instead of trusting the arithmetic. On the Windows build it came back as 4 192 MB against the 4 096 MB of long lived part the profile was owed.

The difference is the short lived part of that build. That number is not one of the hundred steps either, which is the browser answering the second way.

Both shapes of the answer are normal

A profile that always answered with a step would stand out exactly where it tried to blend in, so the shape of the real answer is the shape of ours.

How to read your own

In a Chromium browser, open the developer console, read performance.memory.jsHeapSizeLimit and divide it by 1024 twice for megabytes.

A rounded answer is easy to recognise: three digits and then zeros all the way down. Anything above 3 760 000 000 never came out of the table.

What this does not claim

  • It does not claim that a ceiling in agreement makes a profile safe. One disagreement out of many is removed, and behaviour, payment details and the history of an account stay untouched by any browser.
  • It does not claim that every site reads this. The property is not part of the web standard, and not every browser offers it at all.
  • The short lived part is left alone, so the ceiling never matches the declared memory to the byte. The self-test asks for agreement within a margin instead of an exact number.
  • The hundred steps were computed on the engine generation shipped today. A later engine can move the table, which is why the file is recomputed rather than trusted.

Where you can see this yourself

Every number above comes out of a file you can open and run again.

The hundred steps are computed by a verbatim copy of the engine source
docs/замеры/ступени-памяти-153.cc · docs/замеры/ступени-памяти-153.txt
The table is recompiled and compared step by step
packages/shared/test/ступени-памяти-как-у-движка.js
The ceiling a profile is owed is arithmetic in one place
packages/shared/src/index.js
The engine replaces the long lived part and nothing else
engine/patches/armanos-fp-0012.newfiles.tgz · engine/patches/armanos-fp-0014-memory.diff
The reading taken on the built engine
docs/замеры/приёмка-windows-02-09.json

Questions

Why round the number at all?
A byte count is close to unique for one machine and one build, while a step is shared by a great many. The rounding belongs to the engine and was not invented here.
Is four gigabytes ever shown?
Not by the rounded answer: the highest step is 3 760 000 000 and the table ends there. An exact count can be higher, and on the acceptance run it was.
Does the declared memory move between launches?
No. It comes from the profile seed, so the same profile answers the same way on any machine it opens on.
Can a site tell the value was adjusted?
It reads one ordinary number and cannot see what produced it. What it can see is whether that number agrees with the memory the profile declares.
Does a proxy change any of this?
No. The address arrives from elsewhere, and this number is produced on the machine in front of you.

See your own fingerprint

The check reads 12 values in your browser and sends none of them anywhere. The heap ceiling is not among them.