Solidity – What is the Maximum Size of Memory in Solidity

evmgo-ethereumsolidity

I am digging into memory and the free memory pointer in solidity.

I have been wondering what the maximum size of memory in a single execution of a function in solidity?

As I know, when memory is used, the free memory pointer address is automatically updated at 0x40. I am very curious of what the end of the free memory pointer address will be ?

I tried to figure it out on the remix ide, just like below, but I often got out of gas.

  assembly {
        mstore(0x40, 0xFFFFFF)
    }

It seems I can set the memory pointer onto the maximum number of 32bytes

like this
mstore(0x40, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)

So does it mean by that the maximum size of memory is 32 bytes??

If anybody knows, please let me know it and the reason why?

Best Answer

I just want to extend the answer about theoretical memory size (32-byte address, 2^256 bytes because it's byte-addressable). In reality, if you look at the entire blockchain, it has several limits:

  1. it's bounded by the implementation of the client.
  2. it's bounded by the block gas limit.

For 1., the official Go Ethereum implementation uses Uint64 for memory size, so the memory size is bounded by 2^64 bytes: Go Ethereum Mstore implementation For 2., it's the real limit that you will hit much sooner before the 1. comes, and it's blockchain-dependent and function-type dependent.

For example, the Ethereum blockchain now has ~30M gas (Jan 2023). In practice, the transaction can only spend less than that. So with the approximate equation (X/32)^2/512 + 3X/32 = 30M you found X is approximately a bit higher 0x3C0000. It's the real limit for the current Ethereum blockchain. For BSC, it's higher (~140M Block gas limit).

Function to test gas limit :

contract Test{
    function test()public {
        assembly {
            mstore(0x40, 0x3C0000)
        }
        // The above mstore doesn't cost much gas but it affects the subsequent mstore and mem alloc (the free mem pointer)
        string memory dummy = "test";
        // MSTORE for dummy will extend mem and spend nearly 30M gas.
    }
}

Another concern is the view function when using eth_call directly, as far as I know there is no official upper limit gas spent by eth_call and hence your function may hit the client gas limit in 1.. Unofficially the client or RPC provider will have their own limit on that (e.g. 550M on alchemy). Different clients may have different implementations on this.