Skip to content

do_blocks(): Free up transient memory leak #8999

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

dmsnell
Copy link
Member

@dmsnell dmsnell commented Jun 18, 2025

Trac ticket: Core-63588

There has been a memory inefficiency inside of do_blocks() where it parses the given content then iterates through each top-level block to render it. Unfortunately each top-level block can considerably add to the overall memory use involved, and once moving on to the next top-level block, all of the allocated memory will be retained until the end of the call to do_blocks().

In this change, each parsed block sub-tree is freed via reset to null after it has been rendered. All top-level blocks are rendered independently of each other and so this operation is safe — there are no data dependencies between them.

For a test post of length 2.3 MB containing 138 top-level blocks, this brought the minimum memory requirement for the PHP process down from around 450 MB to around 316 MB. This was “around” since the memory requirements are non-deterministic and some runs will succeed while other runs will crash for out-of-memory given the same memory_limit.

Impact of this change will be most profound when there exist one or more top-level blocks which allocate a significant amount of memory which are not the last top-level-block in a post. This means that this change might even impact small and typical posts, if the right blocks are near the start of the post.

dmsnell added a commit to dmsnell/wordpress-develop that referenced this pull request Jun 18, 2025
There has been a memory inefficiency inside of `do_blocks()` where it
parses the given content then iterates through each top-level block to
render it. Unfortunately each top-level block can considerably add to
the overall memory use involved, and once moving on to the next
top-level block, all of the allocated memory will be retained until the
end of the call to `do_blocks()`.

In this change, each parsed block sub-tree is freed via reset to `null`
after it has been rendered. All top-level blocks are rendered
independently of each other and so this operation is safe — there are no
data dependencies between them.

For a test post of length 2.3 MB containing 138 top-level blocks, this
brought the minimum memory requirement for the PHP process down from
around 450 MB to around 316 MB. This was “around” since the memory
requirements are non-deterministic and some runs will succeed while
other runs will crash for out-of-memory given the same `memory_limit`.

Impact of this change will be most profound when there exist one or
more top-level blocks which allocate a significant amount of memory
which are not the last top-level-block in a post. This means that
this change might even impact small and typical posts, if the right
blocks are near the start of the post.
@dmsnell dmsnell force-pushed the blocks/free-processed-blocks-after-doing-them branch from fdefc5e to 5261e3d Compare June 18, 2025 00:15
There has been a memory inefficiency inside of `do_blocks()` where it
parses the given content then iterates through each top-level block to
render it. Unfortunately each top-level block can considerably add to
the overall memory use involved, and once moving on to the next
top-level block, all of the allocated memory will be retained until the
end of the call to `do_blocks()`.

In this change, each parsed block sub-tree is freed via reset to `null`
after it has been rendered. All top-level blocks are rendered
independently of each other and so this operation is safe — there are no
data dependencies between them.

For a test post of length 2.3 MB containing 138 top-level blocks, this
brought the minimum memory requirement for the PHP process down from
around 450 MB to around 316 MB. This was “around” since the memory
requirements are non-deterministic and some runs will succeed while
other runs will crash for out-of-memory given the same `memory_limit`.

Impact of this change will be most profound when there exist one or
more top-level blocks which allocate a significant amount of memory
which are not the last top-level-block in a post. This means that
this change might even impact small and typical posts, if the right
blocks are near the start of the post.

Fixes #63588
@dmsnell dmsnell force-pushed the blocks/free-processed-blocks-after-doing-them branch from 5261e3d to e4d4f1c Compare June 18, 2025 00:19
@WordPress WordPress deleted a comment from github-actions bot Jun 18, 2025
Copy link

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • The Plugin and Theme Directories cannot be accessed within Playground.
  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Copy link
Member

@joemcgill joemcgill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a smart optimization to me.

pento pushed a commit that referenced this pull request Jun 18, 2025
There has been a memory inefficiency inside of `do_blocks()` where it
parses the given content then iterates through each top-level block to
render it. Unfortunately each top-level block can considerably add to
the overall memory use involved, and once moving on to the next
top-level block, all of the allocated memory will be retained until the
end of the call to `do_blocks()`.

In this change, each parsed block sub-tree is freed via reset to `null`
after it has been rendered. All top-level blocks are rendered
independently of each other and so this operation is safe — there are no
data dependencies between them.

For a test post of length 2.3 MB containing 138 top-level blocks, this
brought the minimum memory requirement for the PHP process down from
around 450 MB to around 316 MB. This was “around” since the memory
requirements are non-deterministic and some runs will succeed while
other runs will crash for out-of-memory given the same `memory_limit`.

Impact of this change will be most profound when there exist one or
more top-level blocks which allocate a significant amount of memory
which are not the last top-level-block in a post. This means that
this change might even impact small and typical posts, if the right
blocks are near the start of the post.

Developed in #8999
Discussed in https://core.trac.wordpress.org/ticket/63588

Props dmsnell, joemcgill.
Fixes #63588.


git-svn-id: https://develop.svn.wordpress.org/trunk@60316 602fd350-edb4-49c9-b593-d223f7449a82
Copy link

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 60316
GitHub commit: 1db3088

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions bot closed this Jun 18, 2025
@dmsnell dmsnell deleted the blocks/free-processed-blocks-after-doing-them branch June 18, 2025 00:50
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Jun 18, 2025
There has been a memory inefficiency inside of `do_blocks()` where it
parses the given content then iterates through each top-level block to
render it. Unfortunately each top-level block can considerably add to
the overall memory use involved, and once moving on to the next
top-level block, all of the allocated memory will be retained until the
end of the call to `do_blocks()`.

In this change, each parsed block sub-tree is freed via reset to `null`
after it has been rendered. All top-level blocks are rendered
independently of each other and so this operation is safe — there are no
data dependencies between them.

For a test post of length 2.3 MB containing 138 top-level blocks, this
brought the minimum memory requirement for the PHP process down from
around 450 MB to around 316 MB. This was “around” since the memory
requirements are non-deterministic and some runs will succeed while
other runs will crash for out-of-memory given the same `memory_limit`.

Impact of this change will be most profound when there exist one or
more top-level blocks which allocate a significant amount of memory
which are not the last top-level-block in a post. This means that
this change might even impact small and typical posts, if the right
blocks are near the start of the post.

Developed in WordPress/wordpress-develop#8999
Discussed in https://core.trac.wordpress.org/ticket/63588

Props dmsnell, joemcgill.
Fixes #63588.

Built from https://develop.svn.wordpress.org/trunk@60316


git-svn-id: http://core.svn.wordpress.org/trunk@59652 1a063a9b-81f0-0310-95a4-ce76da25c4cd
github-actions bot pushed a commit to platformsh/wordpress-performance that referenced this pull request Jun 18, 2025
There has been a memory inefficiency inside of `do_blocks()` where it
parses the given content then iterates through each top-level block to
render it. Unfortunately each top-level block can considerably add to
the overall memory use involved, and once moving on to the next
top-level block, all of the allocated memory will be retained until the
end of the call to `do_blocks()`.

In this change, each parsed block sub-tree is freed via reset to `null`
after it has been rendered. All top-level blocks are rendered
independently of each other and so this operation is safe — there are no
data dependencies between them.

For a test post of length 2.3 MB containing 138 top-level blocks, this
brought the minimum memory requirement for the PHP process down from
around 450 MB to around 316 MB. This was “around” since the memory
requirements are non-deterministic and some runs will succeed while
other runs will crash for out-of-memory given the same `memory_limit`.

Impact of this change will be most profound when there exist one or
more top-level blocks which allocate a significant amount of memory
which are not the last top-level-block in a post. This means that
this change might even impact small and typical posts, if the right
blocks are near the start of the post.

Developed in WordPress/wordpress-develop#8999
Discussed in https://core.trac.wordpress.org/ticket/63588

Props dmsnell, joemcgill.
Fixes #63588.

Built from https://develop.svn.wordpress.org/trunk@60316


git-svn-id: https://core.svn.wordpress.org/trunk@59652 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants