On June 19, 2026, Nothing co-founder Akis Evangelidis explained the decision not to release the CMF Phone 3 Pro smartphone this year. It was not possible to build a model that would look like a step forward compared to the previous one and maintain the same price due to increased memory chip costs. This is the first time a manufacturer has directly cited rising memory prices as the reason for canceling a model, rather than postponing its release. Behind this decision is a broader shift: rising memory chip prices are already putting pressure on the entire market, especially the budget segment, where manufacturers are forced to cut RAM configurations. In practice, this means a specific scenario: the peak memory consumption of an application fits within the budget of a higher-end device, but exceeds the amount of RAM the operating system can provide on a model with less RAM. Previously, engineers would only discover this discrepancy after a production crash. Maxim Martynov, a leading programmer at Playrix with over 10 years of experience in development, an expert judge at AITEX Summit Spring 2026, and a jury member for Cases & Faces, proposed a measurable way to assess this at the design stage. We spoke with Maxim about the conditions under which an allocator holds memory unnecessarily and when it fits within the physical budget of the device.
What standard tests miss
Standard allocator tests, such as Larson and Google Threadtest, measure throughput — the number of memory allocation and deallocation operations a system performs per second. However, they do not show how much memory an allocator holds beyond what is actually used. Martynov encountered this problem in practice: in systems where millions of objects operate simultaneously, it is important to understand how much memory each architecture reserves beyond what is necessary. He did not have a ready-made tool for such an assessment, so he identified a separate metric — the ratio of reserved memory to the peak volume of live data, which he called the overhead coefficient. In his research, this metric is used alongside throughput and load scalability to evaluate the behavior of different allocator architectures. With 4–6 GB of available memory, the size of such a reserve can become a significant architectural limitation.
“A laboratory run and an application running on a real device test different things. A synthetic test takes a matter of minutes and does not show how an allocator behaves when some objects live for seconds, others for hours, and all of this happens in the same memory simultaneously. Therefore, I made the object lifetime model a separate experimental variable, rather than leaving it as a side effect,” Martynov explains.
In other words, an allocator's speed is not equal to its memory appetite: a good result in one metric does not guarantee a good result in another.
Having formalized the overhead coefficient, Martynov moved on to the main question: how do real allocator architectures behave under different load scenarios? In his work “Object Lifetime Models and Their Effect on Performance and Memory Fragmentation in Specialized C++ Allocators,” he compared four allocators: system malloc, monotonic arena (an allocator based on a monotonically growing memory pool), pool allocator (a pool allocator for objects of a single size), and segregated free list (an allocator with free block lists separated by size classes). He built a matrix of 39 controlled scenarios at the intersection of object lifetime models and load characteristics. Long-lived means that objects live for a long time and are deallocated in bulk; FIFO, LIFO, and random describe individual deallocation in different orders. The load characteristic defines what the allocator works with: fixed small size, variable size, or intensive rotation, where objects are constantly created and destroyed. Separately, Martynov tested each allocator with a tenfold increase in load: it is at this limit that architectural assumptions either continue to work or cease to.
What the numbers showed
According to Maxim Martynov's research, in the experiment, system malloc showed the most stable, albeit relatively low, throughput: changes in the object lifetime model and load characteristics affected it less than specialized implementations – in all 39 scenarios, malloc stayed within the range of 0.87–1.07 million operations per second. Where the load corresponds to the assumptions of a more specialized architecture, malloc loses to it by one or two orders of magnitude.
In the same study, a pool allocator for long-lived, fixed-size objects achieved 86.4 million operations per second with an overhead coefficient of 1.000×: all reserved memory was occupied by useful data without any remainder. Martynov recorded that with a tenfold increase in load, the indicator hardly dropped – 81.4 million operations per second. This means that the pool allocator does not lose efficiency with a sharp increase in the number of simultaneously live objects on the scene or the intensity of temporary object creation, as happens in a complex game scene. For individual object deallocation (FIFO, LIFO, random), the same allocator shows 46.0–49.0 million operations per second, below the peak value, but still an order of magnitude higher than malloc.
The third allocator, monotonic arena, maintains 50.3–59.5 million operations per second with a fixed overhead coefficient of 1.25×. In the investigated configuration, monotonic arena was used in scenarios where objects are deallocated in groups: it does not handle individual deallocations, and occupied memory is only returned when the entire arena is reset. A small but constant reserve arises due to the block growth policy, where the current block is filled and the allocator allocates a new one, leaving part of the latter unused.
Martynov obtained the most unexpected result with the segregated free list. With intensive object rotation, when live data is only 8729 bytes, the allocator reserves more than 2 million bytes: the overhead coefficient reaches 236.5×. For variable-sized objects, the overhead remains at 7.6–8.0× with a throughput of 31.2–35.5 million operations per second. In scenarios with long-lived objects, the coefficient, on the contrary, drops below 1× and reaches 0.08×, but this is not a sign of efficiency: the total volume of live objects exceeds the capacity of pre-allocated size classes, and the allocator enters an emergency failure mode instead of saving memory. With a tenfold increase in load, the system enters emergency mode: 2,002,194 events of size class capacity exhaustion. As the specialist notes, the reason is that in the investigated implementation, the segregated free list aggressively pre-allocates size classes: with suitable load, it provides speed, but if there is a mismatch, it wastes memory or leads to service failure.
“Before choosing an allocator, the team needs to fix the size distribution, the range of object lifetimes, the order of deallocation, and the maximum rotation intensity. These four parameters allow for an advance assessment of memory reservation and the risk of size class exhaustion,” comments Maxim Martynov.
None of the four allocators wins in all scenarios at once: the choice always depends on the specific load. The novelty of Maxim Martynov's methodology is that the object lifetime model is used as an independent experimental variable and correlated with throughput, memory reservation, and load scaling. This gives engineers a reproducible way to verify the architecture against the load in advance.
What this means for the industry
The memory price crisis does not change the mathematics of how allocators work: it was the same a year ago, and three years ago. What changes is which of its consequences become noticeable. While a device had 12–16 gigabytes of memory, the gap between reserved and actually used memory remained a detail that could be ignored. With 4–6 gigabytes, it turns into a limitation: an application that technically works with full memory might not fit on a reduced device because the allocator keeps some memory empty as a reserve, and this reserve does not fit into the reduced budget. The choice of allocator architecture ceases to be an optimization detail and becomes part of the specification for the amount of memory available to the product. In practice, this means that an engineer can verify the allocator architecture against the device's memory budget at the design stage, rather than after users of budget smartphones start complaining about application freezes and crashes. For an industry where rising component prices are already changing product lines, Martynov's methodology provides a reproducible way to check the allocator architecture in advance, rather than after the fact, when the application no longer fits within the device's memory budget.