Skip to content

Commit 1db3088

Browse files
committed
do_blocks(): Free up transient memory leak
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
1 parent c117d2d commit 1db3088

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

src/wp-includes/blocks.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,11 +2403,13 @@ function parse_blocks( $content ) {
24032403
* @return string Updated post content.
24042404
*/
24052405
function do_blocks( $content ) {
2406-
$blocks = parse_blocks( $content );
2407-
$output = '';
2406+
$blocks = parse_blocks( $content );
2407+
$top_level_block_count = count( $blocks );
2408+
$output = '';
24082409

2409-
foreach ( $blocks as $block ) {
2410-
$output .= render_block( $block );
2410+
for ( $i = 0; $i < $top_level_block_count; $i++ ) {
2411+
$output .= render_block( $blocks[ $i ] );
2412+
$blocks[ $i ] = null;
24112413
}
24122414

24132415
// If there are blocks in this content, we shouldn't run wpautop() on it later.

0 commit comments

Comments
 (0)