RUNTIME · DATA · AREAS C++ · JVM · EVM
Reviewed · 2026-06-26 Final · v4.0

Final academic teaching note · specification-grounded

A cross-runtime taxonomy
of runtime data areas

C++23 · Java Virtual Machine, Java SE 25 · Ethereum Virtual Machine · Final edition

This final edition compares storage constructs across runtimes that operate at different abstraction levels: a language-level object model realized by native implementations, a managed abstract machine, and a consensus-critical virtual machine. The taxonomy is deliberately analogical: it transfers intuition without claiming that similarly named areas have identical representation, lifetime, ownership, observability, or cost.

1 Purpose 2 Lifetime 3 Management 4 Cost
Scope storage organization, not concurrency memory models Method specification-first comparison, implementation terms labeled Sources C++ storage duration, JVMS SE 25, Solidity docs, EIP-1153, Ethereum EVM docs Edition final synthesis of v1 visual, v2 teaching, v3 academic drafts

Final-edition synthesis

This version keeps the visual and interactive clarity of the early HTML draft, the reader warnings and quick-reference pedagogy of the Markdown draft, and the specification-grounded structure of the academic v3 draft. The terminology pass tightens C++ storage duration, JVMS run-time data areas, Solidity data locations, EVM transient storage, and the distinction between storage organization and concurrency memory models.

Layer 1
Executable Representation
Layer 2
Long-Lived State
Layer 3
Activation / Operand State
Layer 4
Runtime-Allocated Working Data
Layer 5
Execution Context & I/O

Terminology, up front

"Memory model" is reserved here for concurrency semantics (the Java Memory Model; the C++ memory model). This framework is a runtime data-area taxonomy — it classifies where data lives and how long it lasts, not how concurrent reads and writes are ordered. See §9.

Objective. This note compares storage organization across C++23, the Java Virtual Machine (JVMS, Java SE 25), and the Ethereum Virtual Machine (EVM). These systems expose different abstraction levels: C++ specifies object lifetimes and storage-duration categories; the JVM specifies run-time data areas for a managed abstract machine; and the EVM specifies consensus-critical execution state, persistent account storage, and gas-priced computation.

A comparative taxonomy, not a claim of equivalence

Method. The comparison projects specification-defined or documentation-defined constructs onto five analytical layers—executable representation, long-lived state, activation or operand state, runtime-allocated working data, and execution context or I/O—and evaluates each layer by purpose, lifetime, management authority, and cost model. Normative claims, implementation examples, and fork-dependent protocol facts are explicitly separated.

Contribution and limitation. The taxonomy is intended for teaching, review, and transfer of intuition between runtimes. It is not a formal semantics, a performance model, or a promise that similarly placed constructs are architecturally identical. Where the analogy leaks, the note states the leak rather than hiding it.

Contribution and limitation. The taxonomy is intended for explanation, review, and transfer of intuition between runtimes. It is not a formal semantics, performance model, or proof that similarly placed constructs have identical behavior. Where the analogy fails, the failure is stated explicitly in §8.

Keywords: runtime data areas; storage duration; managed runtime; JVM; EVM; persistent state; comparative systems pedagogy.

Normative level

C++ storage durations, JVMS run-time data areas, and consensus-level EVM behavior are treated as the primary source of truth.

Implementation level

ELF/PE sections, HotSpot Metaspace, JIT code caches, and compiler placement decisions are labeled as implementation choices rather than language guarantees.

Pedagogical level

The five layers are an explanatory projection. They support comparison, but they do not erase differences in lifetime, observability, determinism, or cost.

§1 · Motivation

Three specification layers for “a running program”

The systems therefore cannot be compared by names alone. “Stack,” “memory,” “static,” and “storage” denote different mechanisms. A useful comparison must ask the same questions at each level: what a region is for, how long its contents survive, who manages it, and what costs or constraints govern it.

Accuracy discipline

The comparison uses the narrowest accurate term available: storage duration for C++, run-time data areas for the JVM, data locations and execution-frame state for Solidity/EVM, and gas for the EVM cost model. Broader words such as “memory,” “heap,” and “stack” are interpreted only after the runtime context is known.

§2 · The framework

P · L · M · C

For any variable or storage construct, ask four questions before naming the area: Purpose — what is it for? Lifetime — how long can it live? Management — who allocates or releases it? Cost — what resource makes it expensive?

The five-layer lens

Layer naming policy

The final edition uses deliberately abstract layer names: Executable Representation, Long-Lived State, Activation / Operand State, Runtime-Allocated Working Data, and Execution Context & I/O. Short labels such as “code,” “state,” “stack,” “dynamic,” and “runtime” appear only as interface cues. They are not the formal layer names.

For comparative purposes, the note projects each runtime onto five analytical layers and reads each layer along four axes: purpose (what it represents), lifetime (frame, thread, process/VM, transaction, or cross-transaction), management (language, runtime, programmer, or protocol), and cost (machine resources, runtime overhead, or gas). These layers are categories of analysis, not claims that the underlying mechanisms are interchangeable.

Reader warning — Layer 2 is not "persistent" everywhere

In C++ and the JVM, long-lived language/runtime state is normally bounded by process, class, class-loader, or VM lifetime. In the EVM, persistent storage is committed to protocol state and survives across transactions until later execution changes it. “Persistent” therefore means cross-transaction and mutable, not immutable or literally permanent.

Hover or focus a layer — the same layer lights up across all three runtimes. Tab to step through.

C / C++

native process address space

JVM / Java

JVMS run-time data areas

EVM / Solidity

deterministic on-chain machine

§3 · C++23

Language-level storage duration and common process realizations

The C++ standard specifies object lifetime and storage duration, not a required process layout. It distinguishes static, thread, automatic, and dynamic storage duration [1]. Text, data, BSS, TLS, call stacks, registers, and allocator “heaps” are conventional ABI and operating-system realizations of those semantics.

Normative claim vs common realization

“Automatic” does not mean “must be on the stack,” and “dynamic” does not mean “must be in a region named the heap.” Optimizing implementations may keep values in registers, scalar-replace objects, merge constants, or eliminate storage entirely, provided observable C++ semantics are preserved.

storage_duration.cpp

int a = 10;        // static storage duration; commonly writable data
int b;             // static duration; zero-initialization is guaranteed
int c = 0;         // static duration; commonly placed with zero-initialized data
const int D = 42;  // static duration; may be read-only or require no storage
static int e = 5;  // static duration with internal linkage
thread_local int t;// thread storage duration; commonly thread-local storage

int main() {
    int x = 20;            // automatic duration; often a register or stack slot
    int* p = new int(99);  // p: automatic duration; *p: dynamic storage duration
    delete p;              // ends the allocated object's lifetime and releases storage
}

Indeterminate values

The zero-initialization guarantee above applies to static- and thread-storage initialization. A local int b; with automatic storage duration has an indeterminate value; evaluating that value is generally undefined behavior in C++23.

What is distinctive

§4 · JVM, Java SE 25

Specification-level run-time data areas and implementation choices

The JVMS defines logical run-time data areas independently of any particular operating-system layout. Some are shared by all threads and live for the JVM instance; others are created per thread. The core areas are the pc register, JVM stacks, heap, method area, run-time constant pools, and native method stacks [2].

Two levels must remain separate

The JVMS level describes frames, local-variable arrays, operand stacks, the heap, and shared class structures. The implementation level decides how those abstractions map to native memory, registers, compiled code, garbage collectors, and operating-system threads.

Method area, Metaspace, and code cache

The method area is a JVMS abstraction. In HotSpot, class metadata is allocated in native memory commonly described as Metaspace; JIT-compiled machine code is held in implementation-specific code caches. Metaspace is therefore not a portable synonym for the entire method area.

Do not infer physical placement of static fields from the specification

The JVMS associates fields and methods with class structures, but it does not prescribe a physical address-space layout. In HotSpot, JDK 8 removed the permanent generation and moved class metadata into native memory commonly called Metaspace [4]. Static-field values should therefore be described portably as class-associated state; their concrete representation is an implementation detail, not a JVMS guarantee.

Student.java

class Student {
    static int count = 0;  // class-associated state; physical placement is JVM-specific
    String name;           // instance field stored as part of a heap object

    void enroll(String course) {
        int credits = 3;           // logical local-variable slot in this frame
        count++;                   // getstatic / putstatic at the bytecode level
        Student s = new Student(); // reference local; object normally allocated on heap
    }
}
// A JIT may keep locals in registers and may eliminate allocations
// when those optimizations preserve Java's observable behavior.

What is distinctive

§5 · EVM

Consensus-critical frame state and persistent contract state

The EVM is a deterministic state-transition machine executed by Ethereum clients. Each execution frame has code, an operand stack, linear memory, input data, return data, gas, and environmental context; persistent account storage contributes to protocol state. All consensus implementations must reproduce the same valid transition under the active fork rules [5].

The EVM stack is an operand stack

It is not a C/C++-style call stack. Each execution frame manipulates a LIFO stack of at most 1024 256-bit words. Message calls create nested EVM frames; ordinary Solidity internal function calls are usually compiled as control flow within the current frame rather than as new EVM message-call frames.

EVM memory is frame-local linear scratch space

Memory is a byte-addressed, zero-initialized linear array that expands during execution and incurs expansion cost. It has no object-level deallocation or garbage collector. The entire memory instance is discarded when its message-call or creation frame ends.

Counter.sol

contract Counter {
    uint256 public count;                     // persistent storage; mutable across txs
    event Incremented(uint256 value);

    function increment(uint256 amount) external {
        // amount is encoded in calldata and loaded as required
        uint256 next = count + amount;        // usually stack-resident; compiler-dependent
        count = next;                         // SSTORE under active fork gas rules

        uint256[] memory buf = new uint256[](3); // frame-local linear memory
        buf[0] = next;                        // discarded with this external call frame

        emit Incremented(next);               // log entry in the transaction receipt
    }
}

Persistent does not mean immutable

Contract storage survives across transactions, but later execution can update or clear it. Contract code is stored separately and is not writable in place by ordinary EVM opcodes. Protocol rules for account/code lifecycle and gas are fork-dependent.

What is distinctive

§6 · Side by side

Unified comparison with abstraction levels preserved

Analytical layerC++23JVMS 25 / HotSpot noteEVM
Executable RepresentationProgram image; commonly text/code sectionsMethod-area code structures; optional implementation code cacheAccount code executed as EVM bytecode
Long-Lived StateStatic- and thread-duration objects; process/thread boundedClass-associated data; physical placement implementation-specificPersistent storage across transactions; transient storage within one transaction
Activation / Operand StateAutomatic objects and ABI call state; registers or stack are commonPer-thread frames with local variables and operand stacksPer-frame 256-bit operand stack, depth ≤1024
Runtime-Allocated Working DataDynamic-storage objects, commonly allocator-backedHeap objects and arrays, collector-managedFrame-local linear memory; no general object heap
Execution Context & I/OABI, loader, runtime library, unwinding, OS servicespc, native stacks, class loading, GC/JIT internalsGas, calldata, returndata, logs, environment, call-frame context

Axes that differ most

PropertyC++23JVM / JavaEVM / Solidity
Longest internal lifetimeProgram or thread lifetimeJVM, class, or class-loader lifetimeCross-transaction persistent state
Working-data managementScope destruction plus explicit/library-managed dynamic allocationGC-managed heap plus per-thread framesWhole-frame memory discard; protocol-managed state transitions
Execution modelAbstract machine, commonly native codeBytecode with interpreter and/or JIT implementationConsensus stack-machine bytecode
Persistence beyond processExternal files, databases, servicesExternal files, databases, servicesStorage committed to Ethereum protocol state
Determinism obligationNo consensus requirementNo consensus requirementConsensus-critical under fork rules
Addressing modelTyped objects plus raw pointersTyped references; no Java pointer arithmeticStack words, memory byte offsets, storage keys
Cost modelCPU, memory hierarchy, allocator, OSCPU, heap, GC, compilation, native resourcesGas schedule plus protocol limits
Portability boundarySource plus implementation/ABIClass-file version plus platform dependenciesTarget chain and supported EVM fork

§7 · The same source-level idea, three runtimes

A long-lived counter and temporary working data

The examples express the same source-level intent, but their lifetimes are not equivalent: the C++ and Java counters are bounded by a process or class lifetime, whereas the Solidity counter survives across transactions in protocol state.

int counter = 0;   // static duration; commonly writable data
int resetTo;       // static duration; zero-initialized by the language

void add(int amount) {            // ABI may use registers and/or stack
    int next = counter + amount;  // automatic duration; placement may be optimized
    counter = next;
}
int* makeBuffer(int n) {
    return new int[n];            // dynamic storage; caller must establish ownership
}

Placement summary

ItemC++JavaSolidity / EVM
counterStatic duration; commonly data sectionClass variable; JVM-specific physical placementPersistent storage
resetToStatic duration; guaranteed zero initializationClass variable; default zeroPersistent storage; default zero
nextAutomatic object; register or stack are commonLogical local-variable slot; JIT may optimizeUsually operand stack; compiler may spill to memory
array / bufferDynamic storage; ownership requiredGC-managed heap objectFrame-local linear memory
function inputABI-defined registers/stackFrame local-variable array, logicallyCalldata loaded to stack or copied to memory as required

Compiler placement is not source semantics

Comments such as “on the stack” are useful implementation intuition, not universal guarantees. C++ and JVM compilers may use registers or eliminate objects; Solidity's compiler may rearrange or spill stack values while preserving EVM-visible behavior.

§8 · Limits of the analogy

Where the taxonomy leaks

The taxonomy is useful precisely when its limits are visible. Similar purpose does not imply similar lifetime, representation, observability, failure mode, or cost.

Name clashes — the same word denotes different mechanisms

TermC++JVMEVM
StackCommon native call-stack realization; not a required home for every automatic objectPer-thread logical frames, each with locals and an operand stackPer-frame operand stack only; message-call depth is separate
Heap / memory“Heap” is conventional allocator terminology for dynamic storageShared GC-managed object heapmemory is frame-local linear scratch, not an object heap
Static / storageProgram-duration or internal-linkage concepts; process-localClass-associated variables and metadata with JVM-specific layoutstorage is mutable cross-transaction protocol state

Structural mismatches

§9 · Terminology

Why this is called a data-area taxonomy

“Memory model” is overloaded in standards literature. C++ uses the term for foundational notions such as bytes and memory locations and separately specifies multithreaded executions and data races; Java's Memory Model specifies inter-thread visibility, ordering, and happens-before relations [3]. Neither meaning is the subject of this note.

This document instead concerns storage duration, run-time data areas, execution-frame state, and persistent protocol state. “Runtime data-area taxonomy” is therefore the least ambiguous label.

Preferred usage

Use memory model only when the relevant specification uses it; use runtime data areas, storage organization, or data-area taxonomy for the comparative framework here.

§10 · Quick reference

One precise sentence each

C++23

The language specifies object lifetimes and storage durations; native stacks, registers, sections, and allocator heaps are common but non-normative realizations.

JVM SE 25

The JVMS defines logical shared and per-thread run-time data areas, while HotSpot decides their physical native-memory and compiled-code realization.

EVM

Each frame has operand stack and linear memory, while mutable storage persists across transactions and gas prices execution under fork-specific consensus rules.

QuestionC++23JVM / JavaEVM / Solidity
Where is executable code represented?Program image; commonly code/text sectionsMethod-area structures; optional compiled-code cacheAccount code as EVM bytecode
Where is long-lived internal state?Static/thread-duration objectsClass-associated data, implementation-specific placementPersistent or transient storage
Where are temporary scalar values?Automatic objects, often registers/stackLogical frame locals/operand stacksOperand stack, with possible compiler spills
Where are runtime-created aggregates?Dynamic storage or automatic objectsJava heapNo general object heap; temporary arrays/structs use memory
How is working data reclaimed?Scope destruction, RAII, and explicit/library deallocationFrame teardown plus garbage collectionFrame memory discard; state updates committed or reverted
What persists beyond process exit?Only externalized dataOnly externalized dataCommitted contract storage
What constrains execution?Language rules and machine/OS resourcesVM configuration, GC/JIT, native resourcesGas and protocol limits

§11 · Beyond three

Extending the taxonomy cautiously

For another runtime, ask which constructs serve each analytical purpose, then record where the mapping fails.

RuntimeCodeLong-lived stateActivation / operandWorking dataContext / runtime
CLR (.NET)IL + JITMetadata + staticsEval stack / framesManaged heap (GC)Thread, AppDomain, GC
CPythonBytecode (.pyc)Module globals (dict)Frame objectsHeap (refcount + cycle GC)Interpreter loop, GIL
WebAssemblyCode sectionData / global sectionsValue stackLinear memoryHost runtime, imports
Lua VMBytecode (proto)Global table (_G)Lua stackHeap (GC)Lua state, allocator

The lens is a lens, not a law. Some runtimes blur the boundaries (for example, CPython frame objects are heap allocated); others add dimensions such as explicit I/O channels. Use the taxonomy to formulate questions, then verify every claim against the relevant specification and implementation.

§12 · Final checks

Accuracy checklist for readers

The final edition intentionally marks the claims most likely to be mistaught. Use this list when reviewing slides, exam answers, or implementations derived from the taxonomy.

C++Say “storage duration” for the language rule; say “text/data/BSS/stack/heap” only as common implementation vocabulary.
JVMSay “run-time data areas” at the JVMS level; treat Metaspace, code cache, and exact static-field placement as implementation details.
EVM stackCall it an operand stack of 256-bit words, not a native call stack or an object stack.
EVM memoryCall it transient linear scratch space for an execution frame, not a garbage-collected heap and not persistent storage.
Transient storageIt is state-like and transaction-scoped; it is cleared at transaction end and is not committed as persistent account storage.
Memory modelReserve the phrase for specification-level memory/concurrency semantics; this document is a runtime data-area taxonomy.

§13 · Primary sources

References

  1. ISO/IEC. ISO/IEC 14882:2024, Programming Languages — C++. Publicly accessible working draft: Thomas Köppe, ed., Working Draft, Standard for Programming Language C++, WG21 N4950, 10 May 2023, especially §6.7.5 “Storage duration,” §6.7.1 “Memory model,” and §6.9.2 “Multi-threaded executions and data races.” WG21 N4950.
  2. Lindholm, T.; Yellin, F.; Bracha, G.; Buckley, A.; Smith, D. The Java Virtual Machine Specification, Java SE 25 Edition. 29 July 2025, §2.5 “Run-Time Data Areas” and §2.6 “Frames.” Oracle JVMS 25.
  3. Gosling, J.; Joy, B.; Steele, G.; Bracha, G.; Buckley, A.; Smith, D. The Java Language Specification, Java SE 25 Edition. §17.4 “Memory Model.” Oracle JLS 25.
  4. Masamitsu, J. “JEP 122: Remove the Permanent Generation.” OpenJDK, delivered in JDK 8. Establishes the HotSpot implementation change that removed PermGen and moved class metadata to native memory; the final note treats Metaspace as implementation vocabulary, not a JVMS data-area name. OpenJDK JEP 122.
  5. Ethereum Foundation. “Ethereum Virtual Machine (EVM).” Describes deterministic state transition, 1024-entry 256-bit stack, memory, persistent storage, transient storage, and gas. ethereum.org EVM documentation. Consensus-sensitive details should be checked against the current Ethereum Execution Layer Specifications.
  6. Akhunov, A.; Salem, M. “EIP-1153: Transient Storage Opcodes.” Final Core EIP. Specifies transaction-scoped TLOAD/TSTORE, frame sharing, revert behavior, and clearing at transaction end. EIP-1153.
  7. Solidity Project. “Transient Storage in Solidity 0.8.24.” Explains Solidity compiler support for EIP-1153 and notes that transient storage is scoped to the current transaction and reset afterward. Solidity blog — transient storage.
  8. Solidity Project. “Types — Data location,” “Layout in Memory,” and “Layout of State Variables in Storage and Transient Storage.” Data locations; memory layout; storage layout.
  9. Ethereum Improvement Proposals. “EIP-7569: Hardfork Meta — Dencun.” Lists EIP-1153 among the execution-layer changes activated in the March 2024 Dencun network upgrade. EIP-7569.

Accessed: 26 June 2026. Version-sensitive statements are labeled as specification-level, implementation-specific, or fork-dependent. For legal or production-critical work, consult the cited specifications and the implementation or fork actually in use.