Skip to content

View Hive

github-actions[bot] edited this page Oct 13, 2026 · 1 revision

View Hive

Memory drawn as an apiary. Each cgroup (each app on macOS) is a wooden hive, and each of its three largest processes is a honeycomb frame lifted out behind it. A frame is a fixed 64 by 32 comb whose cells count that process's memory by kind: honey is anonymous memory (Pss_Anon), pollen is file-backed memory (Pss_File), royal jelly is shared memory (Pss_Shmem), capped honey is memory swapped out (SwapPss), and brood is the growth of the resident set since the sample before. One bee crawls the comb for each thread, at a speed set by that thread's CPU, and the thread that leads its process is the queen. Where the sampler could not split a process's memory the frame says so in a different colour, and where it could not read it at all the frame is sealed.

Hive: eight wooden beehives on a meadow at dusk, each with three honeycomb frames lifted out behind it, amber honey arching over a ring of brood and orange pollen, pale green frames where the memory is not split, and a few bees crawling on the combs

The README image of the view (docs/media/hive.webp), rendered from the demo workload (--demo --time 12). The design's reference mockup is docs/mockups/hive.jpg; the view follows its geometry, which was ported from docs/mockups/code/hive.py.

The system being modelled

A colony of honey bees (Apis mellifera) lives in wax comb, and a beekeeper's hive holds the comb in removable wooden frames hung side by side in boxes: a frame can be lifted out and looked at, which is what the view does with a process. A full brood frame has a recognisable arrangement. The queen lays in the brood nest in the middle of the frame; round it is a band of pollen, the bees' protein, in cells of the colours of the flowers it came from; above the nest is an arch of honey, and the cells the bees have finished with are capped with wax. The nest is warm and central and the stores are on the cooler edge. A worker cell is roughly 5 mm across: measurements of A. mellifera worker cells run from about 4.6 to 5.5 mm, depending on race and on which of the three directions across the cell is measured, since a cell is not a perfect hexagon.

Three things from the hive reappear in the view as structure, not as data: the cell (a fixed, countable unit, here a quantum of memory), the frame (the bounded container of one process's share) and the bee (an individual actor, here a thread, whose liveliness shows how busy the frame is). The metaphor suits memory because memory is counted in discrete pages, accounted by kind, and shared between processes in a way a frame of comb makes visible. It is a metaphor: a cell is not a page, and the placement of honey above brood is a convention of the beekeeper's picture that the view borrows (see Reading the picture).

History

From wasps to bees. Bees are a lineage of apoid wasps that took to feeding their young pollen. Their closest wasp relatives are not settled in the way the textbook "bees come from the sphecid wasps" suggests: a 2018 phylogenomic study of the Apoidea (Sann and colleagues) found the old wasp family Crabronidae polyphyletic, split it into several lineages, and recovered one of them, the Ammoplanidae (small wasps that hunt thrips, some of which sit on flowers and eat pollen), as the sister group of bees in all its analyses. It put the origin of bees in the Early Cretaceous, about 128 million years ago. Cardinal and Danforth, dating a seven-gene tree of every bee family with fossil calibrations (2013), put the crown group of bees at about 123 million years (113 to 132) and found all the major clades arising in the Middle to Late Cretaceous, when angiosperms were becoming the dominant land plants. The estimates are molecular clocks calibrated on a thin fossil record and differ by a few million years between studies. Where bees arose is also an estimate: Almeida and colleagues (Current Biology, 2023) analysed new genomic and fossil data and concluded that bees originated in Western Gondwana, Africa and South America, shortly before it broke up, and reached the northern continents later through vicariance and dispersal.

The oldest bee fossils. The oldest body fossil that everyone accepts as a bee is a stingless bee in New Jersey amber, described by Michener and Grimaldi in 1988 as Trigona prisca and moved by Engel in 2000 to its own genus, Cretotrigona, as sister to the African genus Dactylurina. Its age was itself argued. Michener and Grimaldi thought the amber about 80 million years old (Campanian); Rasnitsyn doubted it was Cretaceous at all; Grimaldi (1999) supplied evidence for a Late Cretaceous age, and Engel treats it as Maastrichtian, 65 to 70 million years. The surprise was where it sits: a derived stingless bee, in the most derived bee family, that already looked like a living neotropical species. In 2006 Poinar and Danforth described Melittosphex burmensis from Burmese amber about 100 million years old as the oldest bee, with a wasp's body and a bee's branched hairs, in a new family Melittosphecidae. Whether it is a bee is disputed. Danforth and Poinar (2011) kept it as a transitional form closer to bees than to any wasp group; later work on Burmese-amber apoid wasps (Rosa and Melo, 2021) is cited as rejecting even its placement in the Apoidea, and it is now often treated as incertae sedis in the Aculeata (I have not read that paper, so its argument is unverified here). A second Burmese-amber stem bee, Discoscapa apicula (Poinar, 2020), carries pollen in the hair of its middle and hind legs and twenty-one beetle larvae in the same piece of amber, which is as good a record of a flower visit as a fossil gives. Engel's older review also lists claims that failed: an "Early Cretaceous bee" from China that is a sphecid wasp, and Triassic and Jurassic "bee nests" that are the burrows of wasps and beetles.

Sociality arose several times. Of the animals that live in colonies with castes, bees account for several separate origins. Among the halictid (sweat) bees, a molecular-clock study (Brady and colleagues, 2006) found three independent origins of eusociality within a window of about 20 to 22 million years ago, which is why their social behaviour still varies so much within a species. Among the corbiculate bees, the four tribes that carry pollen on a basket (the corbicula) on the hind leg, the picture is older and disputed. The tribes are the orchid bees (Euglossini, solitary or communal), the bumble bees (Bombini, simply eusocial), the stingless bees (Meliponini) and the honey bees (Apini), the last two with queens, workers and perennial colonies. Morphology puts honey bees and stingless bees as sisters, which implies one origin of advanced eusociality. Molecular data since the 1990s put bumble bees and stingless bees together, which implies two. Cardinal and Danforth (2011) dated the first eusociality in the corbiculate ancestor at 87 million years (78 to 95), with advanced eusociality arising separately in honey and stingless bees and eusociality lost in orchid bees. A 2016 phylogenomic study (Romiguier and colleagues) argued that the molecular signal was distorted by GC-rich genes and, once those were controlled for, found the three eusocial tribes forming one clade, which implies a single origin with no reversal. A 2021 morphological study (Porto and Almeida) again recovered honey bees as sister to stingless bees. Phylogenomic work since then agrees that orchid bees are sister to the other three and that bumble bees and stingless bees are sisters; what that means for the number of origins is still argued. Within the whole of the Apoidea, Sann and colleagues found that eusocial societies arose only in one clade, the one that contains the bees.

Apis, and where the honey bee began. The genus Apis is the honey bees proper, and two questions are kept apart in the literature: where the genus arose, and where the western honey bee, A. mellifera, arose. The older apicultural view put the genus in south-eastern Asia, and Ruttner (1988) argued that Oligocene and Miocene honey bees could not have reached Africa. Whitfield and colleagues (Science, 2006), genotyping 1,136 single-nucleotide polymorphisms in 341 bees, concluded that A. mellifera originated in Africa and expanded into Eurasia at least twice ("thrice out of Africa" counts the New World). Cridland, Tsutsui and Ramirez (2017) re-analysed whole genomes and located the origin in the Middle East or north-eastern Africa, noting that earlier studies had reached different conclusions through incomplete sampling. Kotthoff, Wappler and Engel (2013) went to the fossils: the earliest definite Apis are Oligocene bees from Germany and France, the genus was more diverse in the Oligocene and Miocene than it is now, and they concluded that Apis arose in Europe, spread to Asia, Africa and North America, and that A. mellifera descends from European ancestors that crossed to Africa in the late Miocene and returned to Europe in the Holocene. Asia, Africa, the Middle East and Europe have each been named; the question is open, and the three kinds of evidence (living populations, genomes, fossils) do not yet agree.

Honey hunting before hives. The oldest records of people and bees are not of hives. A painted scene in the Cuevas de la Araña at Bicorp, Valencia, shows climbers on ropes reaching a hole in the rock while bees, drawn as dots, fly round it. It was reported by Hernandez Pacheco in 1924 and published in English by Marcel and Lya Dams in Nature in 1977, who attributed it and neighbouring paintings to the Mesolithic. The date is soft: Levantine rock art is dated mostly by style and superposition, and secondary sources give the honey scene as Epipalaeolithic, about 8,000 years old, or more loosely 8000 to 6000 BC. Chemistry gives firmer ground. Roffet-Salque and colleagues (Nature, 2015) found beeswax in the pottery of Neolithic farmers across Europe, the Near East and North Africa, from at least the seventh millennium cal BC.

Pipe hives and the Tel Rehov apiary. The oldest definite evidence of hives is a relief in the sun temple of the pharaoh Niuserre at Abu Ghurab, found by Borchardt in 1898 and dated about 2400 BC (Crane) or 2450 BCE (Kritsky). It shows a beekeeper smoking a stack of horizontal hives and honey being packed in jars. Later scenes survive in the tomb of Rekhmire (about 1450 BC), in a second Eighteenth Dynasty tomb that is badly preserved, and on a pillar in the tomb of Pabasa (660 to 625 BC). Crane and Graham argued from the blue-grey colour that the hives were unbaked clay, like the "pipe" hives still used in Egypt, and noted that the proportions in the paintings (length two to four times the diameter) are stubbier than modern pipe hives (about eight times). No picture of a hive is known from Pabasa until Italian Exultet rolls of about AD 1000. The hives themselves came out of the ground at Tel Rehov in the Jordan valley: about thirty cylinders of unfired clay and straw, in rows three tiers high in a courtyard of a city that fell at the end of the tenth or start of the ninth century BCE, with an estimated 100 to 200 hives in all, found in 2005 to 2007 by Amihai Mazar's expedition. Bloch and colleagues (2010) recovered bees, drones, pupae and larvae from them and found that the bees fit the Anatolian subspecies A. m. anatoliaca, not the local A. m. syriaca. They offer two readings, a rapid change in the range of the subspecies or bees imported for their milder temper and higher honey yield, and the excavators suggest the wax mattered as much as the honey, for the lost-wax casting of bronze. A press estimate that the apiary could give half a ton of honey a year came from visiting beekeepers, not from a measurement.

Skeps. In north-western Europe the hive for most of the last two thousand years was the skep, an inverted basket. Crane and Walker date the earliest known skep fragment, woven wicker, to AD 1 to 200 (Feddersen Wierde, Lower Saxony). Aldhelm, writing about 705, mentions hives of wicker and of bark; coiled-straw skeps came to eastern England with the Saxons after about AD 500. Domesday Book (1086) records hives in several hundred entries, and walls with recesses for skeps are recorded in Britain from the twelfth century (the earliest, at Buckfast Abbey, probably twelfth century). A skep has a fixed comb that cannot be taken out whole, so harvesting honey meant cutting it out, and at the end of summer the beekeeper killed the bees in some of the hives to take their honey and wax and kept others as stock.

Hinged frames and movable bars. François Huber (1750 to 1831) went blind in youth and worked through his servant François Burnens. In letters to Charles Bonnet dated from 1789 he described a "leaf" or "book" hive of twelve vertical frames hinged together, each holding one comb with a few lines of space from the glass, so that every cell of every comb could be inspected on both sides; the letters were published as Nouvelles observations sur les abeilles in 1792. Movable bars were older than any one inventor. Ukrainian sources credit Petro Prokopovych (1775 to 1850) with a frame hive in 1814 (I did not check a primary source), and Jan Dzierzon, a Silesian priest, published from the 1840s a hive of movable bars and the theory that drones come from unfertilised eggs; a letter reproduced in Langstroth's manual dates his first statement of the theory to 1845. Langstroth himself wrote that "there was nothing new in the use of movable bars; the invention being probably, at least, a hundred years old", and that he first heard of Dzierzon in 1851, from the Reverend Dr Berg of Philadelphia.

Langstroth, bee space, and the frame this view draws. Lorenzo Langstroth (1810 to 1895), a Philadelphia minister, built his first hive on Huber's plan, and Huber's hive convinced him that combs could be removed without enraging the bees. A bar hive failed because the bees glued the bars to the walls with propolis or built comb in the gaps. His discovery, in the autumn of 1851 by one secondary account, was the bee space: a gap of about 6.4 to 9.5 mm (a quarter to three eighths of an inch) that bees leave open, neither sealing it with propolis nor filling it with comb. He hung a frame with that gap round it, so that it could be lifted without tearing anything. His US patent 9,300 of 5 October 1852 describes "a movable frame or compound bar" with "about three eighths of an inch space" at its sides; the term "bee space" came later. The patent was reissued on 26 May 1863 (No. 1,484). Accounts disagree about what followed: one says it stayed valid despite many challenges on grounds of prior art, another that Langstroth spent years unsuccessfully defending it against copyists. His Practical Treatise on the Hive and the Honey-Bee appeared in 1853. Two later inventions made frames pay: Johannes Mehring's comb foundation, about 1857, and Franz Hruschka's centrifugal honey extractor, about 1865 (both dates from secondary sources). The frame the view draws is of this kind: a top bar with lugs, two side bars and a bottom bar round a comb.

Why hexagons. Marcus Terentius Varro wrote about the hexagonal comb around 36 BC, and, as Hales retells it, there were two rival theories: that the hexagons suited the bee's six feet, and that the mathematicians were right and the shape was an isoperimetric one. Pappus of Alexandria, whose Book V preface is the classic statement, compares the three regular polygons that tile the plane and says that, for the same material, the hexagon holds more honey; Hales notes that the argument is incomplete, rests on three cases, and excludes gaps for reasons about purity, not mathematics. Kepler (1619) recognised the rhombic base of the cell. Maraldi (1712) measured the base as angles of 109 degrees 28 minutes and 70 degrees 32 minutes; Reaumur set Koenig the problem of the cell with the least material, and Koenig computed 109 degrees 26 minutes and 70 degrees 34 minutes, a difference later put down to an error in his table of logarithms; Maclaurin (1743) got 109 degrees 28 minutes. L. Fejes Toth proved the planar honeycomb conjecture for convex cells in 1943 and showed in 1964 that the three-rhombus cell is not the cheapest one. Darwin (1859) argued that the cells arose by natural selection acting on economy of wax and checked the process with bees that dug pits in a strip of wax; D'Arcy Thompson (1917) argued from foam and surface tension. Hales posted the first general proof of the planar conjecture, without convexity, in June 1999 (arXiv math/9906042); it was published in Discrete & Computational Geometry 25 (2001), and the published version allows disconnected cells and gaps.

The dance. The bees' own code was worked out last. Karl von Frisch showed that a forager returning to the hive dances on the comb and that the dance carries direction and distance (Die Tanze der Bienen, 1946; The Dance Language and Orientation of Bees, 1967), and shared the 1973 Nobel Prize in Physiology or Medicine with Konrad Lorenz and Nikolaas Tinbergen. From the 1960s Adrian Wenner argued that recruits find food by odour. In 2005 Riley, Greggers, Smith, Reynolds and Menzel recorded the flight paths of recruited bees with harmonic radar and gave the first quantitative description of how recruits translate the dance into flight; they note that almost all biologists were by then convinced von Frisch was right. Tania Munz's The Dancing Bees (University of Chicago Press, 2016) is the history of the discovery. Nothing in this view encodes information in the bees' motion.

Theory

Why hexagons: the honeycomb conjecture

A regular $n$-gon of unit area has perimeter $P = 2\sqrt{n\tan(\pi/n)}$, which is 4.559 for the triangle, 4.000 for the square and 3.722 for the hexagon (and tends to the circle's $2\sqrt\pi = 3.545$, which does not tile). The three regular polygons that tile the plane, the triangle, square and hexagon, were known to the Pythagoreans; among them the hexagon needs the least wall, the left panel of the figure below.

The honeycomb conjecture is the stronger statement that no partition of the plane into cells of equal area does better, whatever the shapes of the cells. Hales's Theorem 1-A (read in the arXiv version): let $\Gamma$ be a locally finite graph in the plane made of smooth curves such that $\mathbb{R}^2 \setminus \Gamma$ has infinitely many bounded connected components, all of unit area, and let $C$ be their union. Then

$$ \limsup_{r\to\infty} \frac{\operatorname{perim}\bigl(C \cap B(0,r)\bigr)}{\operatorname{area}\bigl(C \cap B(0,r)\bigr)} \ge \sqrt[4]{12} = 1.861, $$

with equality for the regular hexagonal tiling. A unit-area hexagon has perimeter $2\sqrt[4]{12} = 3.722$ and each wall is shared by two cells, so each cell pays $1.861$. The proof moves the cluster onto a flat torus and rests on a hexagonal isoperimetric inequality (his Theorem 4), a functional uniquely minimised by the regular unit hexagon, with a penalty term that keeps the minimiser from becoming too round. The equal-area condition matters: with unequal areas the problem is a different one. Why bees build hexagons is separate. Thompson's argument is mechanical, not computational: warm wax behaves like a foam, and where three films meet surface tension sets them at 120 degrees, which is the angle of a hexagonal tiling. Whether the bees build hexagons or the wax flows into them, the mathematics of the result is Hales's.

Wall per unit area of regular polygons, one frame of the comb layout the view draws, and the cell unit as the largest frame grows

Left: perimeter of a unit-area regular polygon; yellow marks the three that tile the plane. Middle: one 64 x 32 frame filled in the arrangement of Lattice::arrange in src/hive.rs (brood in the centre, pollen around it, royal jelly below, honey in an arch above, capped honey after it) from a made-up split of 1,160 cells; the colours are the figure's own, not the view's. Right: the cell unit rule with its hysteresis, next_unit. Script: docs/figures/hive-honeycomb-frame.py.

Geometry used by the view. In an offset ("brick") layout of pointy-topped hexagons with cell width $w$ (flat to flat), the columns are $w$ apart and the rows $\tfrac{\sqrt3}{2}w$ apart, every other row shifted by $w/2$; the circumradius is $w/\sqrt3$ and the area $\tfrac{\sqrt3}{2}w^2 = 0.866,w^2$. The comb has 64 cells in every row, odd rows shifted half a cell, so 64 by 32 is 2,048 cells in a box COMB_WIDTH = 64.5 pitches wide and $31\cdot\tfrac{\sqrt3}{2} + 2/\sqrt3 = 28.0015$ pitches high (COMB_HEIGHT), where a pitch is the distance between neighbours in a row.

Memory accounting: RSS, PSS and the rollup

A process's resident set size (RSS) counts every resident page it maps, so a page shared by $n$ processes (a shared library, a shared-memory segment, a copy-on-write page after fork) is counted in full in each. The proportional set size (PSS) divides each resident page by the number of processes that map it:

$$ \mathrm{PSS}_p = \sum_{\text{pages } q \text{ mapped by } p} \frac{1}{n_q}, $$

so that $\sum_p \mathrm{PSS}_p$ counts each mapped page once. Linux exposes it per mapping in /proc/<pid>/smaps and summed over the address space in /proc/<pid>/smaps_rollup, which kernels since 4.14 provide. The fields the view reads are in Rollup (src/model.rs):

Field Meaning
Pss the proportional share, defined above
Pss_Anon, Pss_File, Pss_Shmem the PSS split into anonymous memory (heap, stack), file-backed pages, and shared memory (shmem, tmpfs, memfd); Option fields, None on a kernel before 5.3
SwapPss the proportional share of pages swapped out
Rss, Shared_*, Private_*, Swap read into the rollup but not drawn

Because PSS is relative to the other processes, a frame can change without its process doing anything: when a second process starts to share a library the first one's Pss_File falls. Reading smaps_rollup walks the page tables, so its cost grows with the address space, and it is allowed only for processes the reader may ptrace. Both facts shape the source: the rollup is read only for the ROLLUP_PROCESSES (64) processes with the largest RSS, on the background thread, in a ROLLUP_BUDGET of 50 ms that resumes where it stopped.

The cell unit and its rounding

All frames share one unit $u$, a power of two in bytes at least 64 KiB, so that frames are comparable. A component of $b$ bytes becomes $\lfloor b/u + \tfrac12\rfloor$ cells, a half rounding up, and each component is rounded alone, so a frame of at most five components is off from its true total by at most three cells. The target unit is the smallest with the largest frame at most 2,000 cells, which with the 3-cell margin leaves it inside 2,048. To keep the picture from changing scale at every sample the unit is kept while $700,u \le \text{largest} \le 2000,u$ (or while it is 64 KiB and the largest frame is below 700 cells), so growth through 2,000 cells doubles the unit once, to just over 1,000 cells of the new unit, and the frame can then shrink to 1,400 cells of the old unit, 700 of the new, before the unit halves again. Examples computed from the rule: a largest frame of 100 MiB is 1,600 cells at 64 KiB; 125 MiB is 2,000; 126 MiB moves to 128 KiB (1,008 cells); 1 GiB gives a 1 MiB unit (1,024 cells), 8 GiB gives 8 MiB and 64 GiB gives 64 MiB, each 1,024 cells.

Bees: threads, queens and speed

In Linux every thread is a task with its own tid and its own CPU time, and the thread whose tid equals the pid is the thread group leader (the oldest thread on macOS). The view draws one bee per thread and gives the leader the queen's role. The role is positional: a real colony has one queen and thousands of workers, and every process has one leader. A bee's speed in cells per second is

$$ v = 0.25 + 9\sqrt{c/100}, \qquad c \ge 3\ (\text{percent of one core}), $$

and 0 below 3 per cent, so a thread at the threshold walks at $0.25 + 9\sqrt{0.03} = 1.81$ cells a second, a thread using a whole core at 9.25, and the law is a convention with a jump at the idle threshold. The square root spends the range on the first few per cent of CPU.

Mapping

Visual element Measured quantity (source) Transform
Hive the cgroup of a process, cells::cell_name (Process.cgroup, else Process.group; the app on macOS) at most MAX_HIVES = 8, ranked by the sum of Process.memory over every process in the hive from the sample (RSS on Linux, physical footprint on macOS), whatever its rollup; a shown hive is replaced only by a challenger that outweighs the lightest shown by 25 % (REPLACE = 5/4)
Hive label the group's name cells::short, then +N more for the N processes of the hive that are not among its frames
Hive trim Process.kind of the hive's largest process the kind colour from palette (kernel, system, session, container)
Frame a process: the FRAMES = 3 largest in its hive by Process.memory, ties by Identity a process keeps the lowest free slot while it stays among the three; frame $j$ stands back $0.5 + 0.4j$ and aside $0.1j$ world units from its hive, lifted to $(1.72 + 0.5 + 0.78j)\cdot 0.866$, and is $12,%\cdot j$ darker (dim)
Frame tag Process.kind the kind colour (palette::kind_color) on the top bar
One cell a quantum of memory, the same in every frame next_unit: a power of two from 64 KiB, at most 2,000 cells in the largest frame, shown in the legend
Honey cells Pss_Anon (Process.memory_detail, Source::MemoryDetail; Linux 5.3 or later) $\mathrm{round}(\text{bytes}/u)$ cells
Pollen cells Pss_File the same
Royal jelly cells Pss_Shmem the same
Capped honey cells SwapPss the same
Brood cells growth of Process.memory since the sample before (the shared History) $\max(0, m_\mathrm{now} - m_\mathrm{before})$ in cells, carved out of honey (out of pale nectar on an unsplit or Pss frame) and never more than it; reverts to honey when growth stops
Pale nectar cells (unsplit frame) Process.memory, for a rollup still Pending, or with Source::MemoryDetail missing (macOS) one kind, same unit; this is a measured total, not a substitute for the split
Pale nectar cells (Pss frame) Pss, with SwapPss as capped honey, on a kernel before 5.3 one kind, same unit
Sealed frame an Unreadable rollup a uniform wax cap, no cells and no bees, labelled sealed: smaps_rollup unreadable; not counted toward the largest frame
Bee a thread: Process.thread_list (Source::Threads) at most MAX_BEES = 200 a frame, listed threads first, then bees with no reading up to Process.threads; the rest is a +N bees label
Bee speed Thread.cpu, percent of one core $0.25 + 9\sqrt{c/100}$ cells/s; below 3 % (IDLE_BELOW) the bee walks home and stands still
Queen Thread.leader (tid equals pid on Linux, the oldest thread on macOS) 1.37 times larger (QUEEN_SIZE), a mark in the process's kind colour, at most 0.6 cells/s (QUEEN_SPEED); stands in the nest when idle
Bee with no reading Thread.cpu of None: a first observation, a thread beyond an incomplete list, a list not read never given a speed; stands in the idle cluster; counted in the legend
Where each kind sits in the frame none convention: brood in the centre, pollen around it, royal jelly below, honey above in an arch, capped honey and nectar after it; the counts are real, the arrangement is documented as a convention
Wood, lid, stand, landing board, lift beam, meadow, wings and their flap, cell gloss, pollen colours, larva shape and size (four stages by rank in the brood order), where a busy bee starts and its path, where an idle bee stands none decorative

How isotop realises it

Module and registry row. src/hive.rs holds Hive, which implements views::ViewModule (draw and legend; no record, key, inspector_line or card), and one row of views::REGISTRY: ViewInfo::new("hive", "HIVE", Backdrop::Dusk, ...) with link_strokes: true (sockets join the frames of the processes that hold them as hairlines), face: Some(|_, goal| (goal.rotation, goal.pitch)) (a frame stands high above the ground under it, so a tour or a search centres the frame, and the camera is left as it is), sources: Sources::of(&[Source::MemoryDetail, Source::Threads]) (the rollup and the per-thread pass are read only while the view is shown), demo: DemoOptions { oom_and_memory_detail: true, threads: true, .. } and a warm-up of Phase::Play { seconds: 10, step: 0.05 } under When::DemoHeadless. It has no view-local keys and the hives are not pickable; the wood, comb and bee triangles of a frame pick its process. There is no plugin system: the view is compiled in.

Data path. grouped takes the slice of processes Scene drew but reads each from snapshot.processes by Identity, so a comb follows the sample and not the scene's eased copy, and a comb is repainted when a sample arrives and not on every frame. Hive::choose keeps the shown hives that still exist, fills empty places from the ranked list and lets a challenger outweigh the lightest shown hive by 25 %; layout::Discs places each hive on the ground as a disc of HIVE_RADIUS 1.75 keyed by hive name, so a hive keeps its place; Hive::seat gives each of the three largest processes the lowest free slot and frees a slot when its process leaves the top three. The brood reads the sample before from stage.history (previous_sample, over the shared History that Scene fills on every sample in every view), so it is right on the first frame after a view switch.

What a frame shows (Measure::of). A missing Source::MemoryDetail comes first: the frame is Unsplit whatever the rollup says. Otherwise Measured::Known with all three Pss_ parts present and Source::MemorySplit not missing is Split; Known without them is Pss (Pss as one pale-nectar kind plus SwapPss); Unreadable is Sealed with no growth; Pending is Unsplit from Process.memory. Counts::of turns each part into cells at the scene's unit, takes the brood out of honey (Split) or nectar (the others), and returns nothing for a sealed frame. Hive::settle takes next_unit over the largest non-sealed frame, and with no frame the unit holds (64 KiB at the start).

The comb (Lattice, Comb). The comb is one render::Field of NODES_X by NODES_Y nodes (517 by 225, 8 texels to a cell pitch) drawn on a vertical four-corner quad with Placement::Corners and Relief::Flat, its owners all the frame's process so a pixel picks it. Lattice is built once on first use: the cell and the offset from its centre under each texel, the order each kind fills the cells in, and the colour of each of 23 "looks" (empty, honey, capped, jelly, nectar, six pollen colours, twelve larvae: four sizes in three turns) at every offset. Lattice::arrange ports the prototype's Comb.layout: the nest is a point at (COMB_WIDTH/2, 0.58 COMB_HEIGHT) and distances scale $x$ by $1/1.55$; brood takes the free cells nearest it, then pollen the next ring, royal jelly the cells ordered by distance minus $0.9,dy$ (so below the nest), then honey, capped honey and nectar in an arch metric in which a cell above the nest counts as nearer than one below (reach $0.42,dy$ above, $2.6,dy$ below, $x$ weighted $0.8$); every order breaks ties by cell index, so the same counts always make the same comb. The larva is larger toward the middle: the innermost quarter of the brood is the largest of four sizes. Comb::update repaints the field only when the looks change and bumps Field.revision for what changed, and a frame behind the first is dimmed by Shading with ambient dim(slot).

The bees (wishes, Swarm, Bee). A frame has min(200, Process.threads) bees. Listed threads come first (the leader leads the list), each keyed by thread_key, a hash of start and tid that the system does not reuse together; the rest are keyed by index with no CPU reading, and when the leader is not listed the first of them is the queen. A bee's random stream is Rng::for_identity(process.id, SALT ^ key), so it keeps its path while its thread lives. Bees step through FixedStep::new(0.05, 10, 0.5) (STEP 0.05 s, at most 10 steps a frame, a gap over 0.5 s counted as 0.5 s) and are drawn interpolated (Bee::pose). A busy bee relaxes toward its speed, turns by a smoothed random angle and reflects at a margin of 0.7 pitches from the edge; a bee with no CPU, or below 3 %, walks home at 2 cells a second and stands there: idle workers in a cluster to the left of and above the nest, the queen in it. A bee is at most eight triangles (two wings, two abdomen, a stripe, a thorax, a head and, for the queen, her mark), lifted toward the viewer by a depth bias per bee and per layer so that no two lie at the same depth; wings are drawn only when the bee is at least WINGS_FROM = 6 px long.

The rest of the picture. draw_ground lays a meadow of 1 by 1 quads with a seeded shade and a four-sided slab edge; draw_hive builds each hive with geometry::cuboid (stand, two boxes with a trim band in the kind colour, a lid, an entrance slot); draw_beam adds four Item::Puff splats between lid and frames. draw_wood is the frame (top bar with lugs, side bars, bottom bar, the kind tag) and a selected process gets a hairline rectangle. A sealed frame is a wax-coloured quad over the comb area and a label. Everything is triangles, hairlines, Item::Puff and an opaque Item::Field, so the CPU and GPU backends agree.

Outputs to the stage. stage.positions holds each frame's centre (picking, labels, exit rings and the tour read it); stage.tour visits frames by memory; stage.titles carries each hive's short name with +N more; stage.places carries +N bees and the sealed label; stage.notes for a frame lists MiB per component (honey | pollen | royal jelly | capped, or Pss | capped, or RSS (unsplit)), brood X (RSS growth) when positive, N threads, M bees and the busiest listed thread, whose name is raw and cleaned by the popup path (terminal::clean_text). stage.bounds is the box round the shown hives' discs from the ground to the top of the third frame, rebuilt only when the discs change. draw returns the number of frames drawn, so cost is bounded by 8 hives x 3 frames and 4,800 bees whatever --processes is.

Legend. 1 cell = <unit> | H hives (+X), F frames, U unsplit, C counted, B bees (S without thread CPU), where the unit is whole KiB, MiB or GiB (unit_text), X counts hives not shown, C counts processes of shown hives without a frame, and U and S are left out at zero; then status::missing_note for memory detail (cells = RSS or cells = memory footprint) and for memory split (cells = Pss and SwapPss), then status::sources_note, then | hive = cgroup | frame = process (top 3 by RSS) | honey = Pss_Anon, pollen = Pss_File, royal jelly = Pss_Shmem, capped = SwapPss, brood = RSS growth | bee = thread, speed = thread CPU, queen = leader, with app for cgroup on macOS.

Platforms and degradation. Linux: everything above; on a kernel before 5.3 the frames are Pss with the memory split note, and another user's processes without privileges are sealed (rollup) and their bees stand in the idle cluster (threads). macOS: the view is available but degraded, Source::MemoryDetail is always missing, so every frame is unsplit from the physical footprint, never sealed, and the legend says | no memory detail: cells = memory footprint; hives are apps; brood works from footprint growth; per-thread CPU comes from the thread reader for readable processes. I did not run it on a Mac (unverified).

Headless warm-up, demo and tests. A demo run replays the ten seconds before --time through Phase::Play as a live run would have drawn them (a frame every 0.05 s, none rasterized), so bees are spread over the combs and brood is measured against the sample before; the demo takes the rollups of DemoOptions::oom_and_memory_detail and the threads of DemoOptions::threads, and the memory oscillation of model::demo gives the brood. The demo's district-NN groups fill the eight hives. Tests in src/hive.rs cover the cell counts of a smaps_rollup fixture, the unit and its band, brood and its reversion, sealed, unsplit and Pss frames, the arrangement, the 200-bee cap and the queen, idle and busy bees, bees with no reading, equal paths at 10 and 60 frames a second, stable places under churn, the legend order and the demo; the view is also covered by the harness checks of every row (harness.rs), with the default contract.

Where the code departs from issue #46. The brood comes from the shared History, not from a record hook of the view; the warm-up is Phase::Play, not a hand-written replay; cuboid is geometry::cuboid and hives are placed by layout::Discs (the issue names coop::cuboid and pack::Discs); and the comb is 64 cells in every row, 2,048 cells, not the 2,032 of the prototype's alternating 64 and 63. The old design page of this view got that last number wrong.

Reading the picture

  • Cell counts are measured; their arrangement is not. The number of honey, pollen, jelly, capped and brood cells follows the rollup within half a cell per kind. Where those cells sit follows the beekeeper's convention. A honey cell at the top of the arch is no older or newer than one at its edge.
  • A unit change changes every frame at once. When the largest frame outgrows 2,000 cells the unit doubles and every comb halves its cell count. The legend shows the unit, and a cell is comparable between frames only within one scene.
  • PSS is relative. A frame can change because another process started or stopped sharing a library. Honey (Pss_Anon) is the least relative, since anonymous pages are mostly private; pollen and royal jelly are the most.
  • Brood is growth, not birth. It is $\max(0, \mathrm{RSS}\mathrm{now} - \mathrm{RSS}\mathrm{before})$ between two samples, resident memory that is new, and it is capped at the honey it is taken from. It does not say the growth is permanent, and it reverts when growth stops. A shrinking process shows no brood.
  • Unsplit, sealed and counted are three different things. An unsplit frame has a measured total but no kinds (a process outside the 64 largest, or not yet reached, or any process on macOS); a sealed frame could not be read at all, typically another user's process; a counted process is in a shown hive but outside its top three and has no frame.
  • Pale green is not a kind. Pale nectar means "no split available", not memory of some fourth type.
  • Bees are threads, capped at 200. A process with 1,000 threads shows 200 and a label for the other 800. Idle bees stand in a cluster, and so do bees whose CPU is not known; the legend counts the latter. A bee's position on the comb carries no data.
  • The queen is the leader, not a unique entity: every process has one.
  • Resolution. A frame holds up to 2,000 cells and is a few hundred pixels wide at 1,600 px, so a cell is one to three pixels across and the kinds read as areas, not counts.

Try it

Commands run with the release binary on Linux (x86_64, CPU renderer), repository root:

./target/release/isotop --list-views
./target/release/isotop --demo --view hive --time 12 --width 1600 --output /tmp/hive.png --renderer cpu
./target/release/isotop --demo --view hive --time 12 --width 1600 --renderer cpu --benchmark 30

The first lists the registered views with hive after hr and before switchboard. The second wrote 1600x900, 24 visible (8 hives of 3 frames). The third reported 20.3 renderer frames per second on this machine at 1600 wide, 49 ms a frame (the binary here may predate the last fixes; a different machine and width will differ). Live: ./target/release/isotop --view hive, or Tab and the v picker; Space visits frames heaviest first; there are no view-local keys. cat /proc/<pid>/smaps_rollup shows the figures a frame is made of for one process.

Where in the code

Item Path and symbol
The view src/hive.rs: Hive, Hive::choose, Hive::seat, Measure::of, Counts::of, next_unit, Lattice, Lattice::arrange, Comb, wishes, Swarm, Bee, bee_speed, draw_bee, draw_hive, draw_wood
Registry row src/views.rs: REGISTRY row hive
Hive grouping src/cells.rs: cell_name, short
The sources Rollup, ROLLUP_PROCESSES in src/model.rs; Source::MemoryDetail, Source::MemorySplit, MEMORY_LABEL in src/platform/mod.rs; smaps_rollup parsing in src/platform/linux/memory.rs; Thread, ThreadList in src/threads.rs
Shared helpers layout::Discs, simulation::FixedStep, Rng::for_identity, geometry::cuboid, history::History, status::missing_note, status::sources_note, src/render/field.rs (Field, Placement::Corners)
Figure docs/figures/hive-honeycomb-frame.py
Prototype (reference only) docs/mockups/code/hive.py: Comb.layout, draw_cell, draw_bee, frame_rect, frame_geometry
Specification issue #46, docs/briefs/views-2026-10.md

Variations and open questions

  • Shared combs. The brief's out-of-scope mode: resolve Pss_File by backing file from /proc/<pid>/smaps every 15 s, so each shared library becomes a communal comb whose cells are coloured by the processes that share it.
  • A waggle dance. Let a thread that migrates between CPUs dance: an angle for the direction of the new core and a duration for the distance. Process.core and per-thread CPU partly exist; nothing in the bees' motion carries data now.
  • The same cgroup twice. View Coop draws a cgroup as a henhouse of hens, and View Cells as a petri dish; this view draws it as a hive of bees. They hold the same processes, and no page takes a position.
  • Swarming. A fork storm (a container starting) is the colony reproducing; a new hive could be founded by bees leaving an old one, driven by Snapshot.life events.
  • The idle threshold. A thread at 2.9 % stands still and one at 3.0 % walks at 1.8 cells a second. A smooth law ($v \propto \sqrt{c}$ from zero) would remove the jump and lose the cluster.
  • Cell unit as information. Each component loses at most half a cell. A per-frame display of the rounding error would show how much of the picture is quantisation.
  • A Fejes Toth cell. The comb is drawn flat; the three-dimensional cell is not drawn at all. A frame seen edge on could show the rhombic base, and the cheaper cell of Fejes Toth (1964).
  • Pollen by file. The six pollen colours are decorative; colouring a cell by the backing file would be the shared-combs mode in miniature.

References

  • T. C. Hales, "The honeycomb conjecture", Discrete & Computational Geometry 25 (2001) 1-22 (arXiv math/9906042, posted 1999).
  • D. W. Thompson, On Growth and Form, Cambridge University Press (1917); C. Darwin, On the Origin of Species (1859), chapter 7; Pappus of Alexandria, Synagoge (Collection), Book V (fourth century); M. T. Varro on agriculture, as retold in Hales's introduction; J. Wyman, "Notes on the cells of the bee" (1866).
  • L. Fejes Toth on the honeycomb conjecture for convex cells (1943) and on the cell of the bee (1964), as cited in Hales's introduction; G. F. Maraldi, "Observations sur les abeilles", Memoires de l'Academie royale des sciences (1712).
  • M. Sann et al., "Phylogenomic analysis of Apoidea sheds new light on the sister group of bees", BMC Evolutionary Biology 18 (2018) 71.
  • S. Cardinal and B. N. Danforth, "Bees diversified in the age of eudicots", Proceedings of the Royal Society B 280 (2013) 20122686; "The antiquity and evolutionary history of social behavior in bees", PLoS ONE 6 (2011) e21086.
  • E. A. B. Almeida et al., "The evolutionary history of bees in time and space", Current Biology 33 (2023) 3409-3422.
  • C. D. Michener and D. A. Grimaldi, "The oldest fossil bee: apoid history, evolutionary stasis, and antiquity of social behavior", Proceedings of the National Academy of Sciences 85 (1988) 6424-6426; M. S. Engel, "A new interpretation of the oldest fossil bee (Hymenoptera: Apidae)", American Museum Novitates 3296 (2000).
  • G. O. Poinar Jr. and B. N. Danforth, "A fossil bee from Early Cretaceous Burmese amber", Science 314 (2006) 614; B. N. Danforth and G. O. Poinar Jr., Journal of Paleontology 85 (2011) 882-891; B. B. Rosa and G. A. R. Melo, Cretaceous Research 122 (2021) 104770; G. O. Poinar Jr., on Discoscapa apicula and the family Discoscapidae (2020; venue not checked).
  • S. G. Brady, S. Sipes, A. Pearson and B. N. Danforth, "Recent and simultaneous origins of eusociality in halictid bees", Proceedings of the Royal Society B 273 (2006) 1643-1649; J. Romiguier et al., "Phylogenomics controlling for base compositional bias reveals a single origin of eusociality in corbiculate bees", Molecular Biology and Evolution 33 (2016) 670; D. S. Porto and E. A. B. Almeida, Insect Systematics and Diversity 5(3) (2021) (title not recorded here); B. N. Danforth, S. Cardinal, C. Praz, E. A. B. Almeida and D. Michez, "The impact of molecular data on our understanding of bee phylogeny and evolution", Annual Review of Entomology 58 (2013) 57-78.
  • C. W. Whitfield et al., "Thrice out of Africa: ancient and recent expansions of the honey bee, Apis mellifera", Science 314 (2006) 642-645; J. M. Cridland, N. D. Tsutsui and S. R. Ramirez, "The complex demographic history and evolutionary origin of the western honey bee, Apis mellifera", Genome Biology and Evolution 9 (2017) 457-472; U. Kotthoff, T. Wappler and M. S. Engel, "Greater past disparity and diversity hints at ancient migrations of European honey bee lineages into Africa and Asia", Journal of Biogeography 40 (2013) 1832.
  • M. Dams and L. Dams, "Spanish rock art depicting honey gathering during the Mesolithic", Nature 268 (1977) 228-230; E. Hernandez Pacheco, Las pinturas prehistoricas de las Cuevas de la Arana (Valencia), Memoria 34, Comision de Investigaciones Paleontologicas y Prehistoricas, Madrid (1924); M. Roffet-Salque et al., "Widespread exploitation of the honeybee by early Neolithic farmers", Nature 527 (2015) 226-230.
  • E. Crane and A. Graham, "Bee hives of the ancient world", Bee World 66; G. Kritsky, "Beekeeping from antiquity through the Middle Ages", Annual Review of Entomology 62 (2017); E. Crane, The World History of Beekeeping and Honey Hunting, Duckworth (1999); E. Crane and P. Walker, "Early English beekeeping: the evidence from local records up to the end of the Norman period", The Local Historian 29(3) (1999) 130-151.
  • A. Mazar and N. Panitz-Cohen, "It is the land of honey: beekeeping at Tel Rehov", Near Eastern Archaeology 70(4) (2007); G. Bloch et al., "Industrial apiculture in the Jordan valley during Biblical times with Anatolian honeybees", Proceedings of the National Academy of Sciences 107 (2010) 11240-11244; A. Mazar, N. Panitz-Cohen and G. Bloch, "The apiary at Tel Rehov: an update", Near Eastern Archaeology 85(2) (2022).
  • F. Huber, Nouvelles observations sur les abeilles (Geneva, 1792; second edition 1814); L. L. Langstroth, US Patent 9,300 (5 October 1852; reissued 26 May 1863 as No. 1,484) and A Practical Treatise on the Hive and the Honey-Bee (1853; the text quoted above is a later manual on Project Gutenberg, edition not identified).
  • K. von Frisch, Die Tanze der Bienen (1946) and The Dance Language and Orientation of Bees, Harvard University Press (1967); J. R. Riley, U. Greggers, A. D. Smith, D. R. Reynolds and R. Menzel, "The flight paths of honeybees recruited by the waggle dance", Nature 435 (2005) 205-207; T. Munz, The Dancing Bees: Karl von Frisch and the Discovery of the Honeybee Language, University of Chicago Press (2016).
  • The Linux kernel documentation, Documentation/filesystems/proc.rst: /proc/<pid>/smaps and smaps_rollup.
  • See also View Cells, View Coop, Theory Stable Layout, Theory Text Safety.

Clone this wiki locally