Report on the feasibility of memory separation for static and global variables #12
Replies: 4 comments 4 replies
-
Analysis of Isolation Options for CoroutinesOption 1: GLOBALS OnlyWhat is isolated:
Implementation: ✅ Works without issues For WordPress:
Benefit: Medium. WordPress heavily uses global variables, but also frequently uses static for caching. Option 2: GLOBALS + Function Static VariablesWhat is isolated:
Implementation: ✅ Works without issues For WordPress:
Isolation example in WP: function get_post($id) {
static $cache = []; // ← WILL be isolated!
if (isset($cache[$id])) return $cache[$id];
// ...
}Benefit: High! Covers ~80-90% of static usage cases in WordPress. Option 3: All Static + GLOBALSWhat is isolated:
Implementation:
For WordPress:
But how critical is it? WordPress rarely uses class static properties:
Benefit: Low additional benefit (covers remaining 10-20%). Application-Wide Performance ImpactOption 1 (GLOBALS only):Overhead: 0% Option 2 (GLOBALS + function statics):Overhead: ~0-2% on entire application
Option 3 (all static):Overhead: ~5-15% on entire application
Recommendation for WordPressOptimal choice: Option 2 (GLOBALS + function statics) Why:
Don't implement Option 3 because:
ConclusionFor production WordPress: Gains:
Future: Technical DetailsCurrent Implementation StatusFrom the discussion at #12: Successfully implemented:
Critical challenge:
Proposed Solution for Option 3if (CACHED_PTR(cache_slot + sizeof(void *)) != NULL) {
if (UNEXPECTED(ZEND_ASYNC_CURRENT_COROUTINE)) {
zend_class_entry *ce = CACHED_PTR(cache_slot);
property_info = CACHED_PTR(cache_slot + sizeof(void *) * 2);
// Hash lookup by CE to get coroutine-specific table
zval *table = coroutine->static_members_ht.find(ce);
result = table + property_info->offset;
} else {
result = CACHED_PTR(cache_slot + sizeof(void *));
}
}Performance characteristics:
Memory FootprintPer coroutine:
For 1000 concurrent coroutines:
|
Beta Was this translation helpful? Give feedback.
-
Static Variable Usage Analysis: WordPress vs LaravelExecutive SummaryThis report analyzes static variable usage patterns in WordPress and Laravel frameworks to determine optimal isolation strategies for PHP coroutines. WordPress Core AnalysisStatic Variable Usage PatternsFunction-level static variables (10-15 occurrences): functions.php:
load.php:
plugin.php:
Class static properties:
Primary Caching MechanismsWordPress prefers:
Conclusion✅ Function static variables: MODERATE usage (~10-15 cases) Laravel Framework AnalysisStatic Property Usage PatternsIlluminate\Support\Facades\Facade.php (3 properties):
Illuminate\Database\Eloquent\Model.php (13 properties):
Illuminate\Support\Str.php (6 properties):
Illuminate\Container\Container.php (1 property):
Illuminate\Routing\Router.php (1 property):
Other core classes:
Function-level static variables:
Conclusion✅ Class static properties: HEAVY usage (~24+ properties) I/O Operations and Static CachingCritical Finding: No I/O Result Caching in Static PropertiesWhat Laravel Caches in Static Properties✅ Pure in-memory transformations (CPU-only):
✅ Object references (no I/O state):
✅ Configuration and metadata:
What Laravel Does NOT Cache in Static Properties❌ Database query results:
❌ File system operations:
❌ HTTP responses:
Detailed AnalysisIlluminate\Support\Facades\Facade: protected static $resolvedInstance; // Caches service instances
Illuminate\Support\Str: protected static $camelCache = [];
public static function camel($value) {
if (isset(static::$camelCache[$value])) {
return static::$camelCache[$value];
}
return static::$camelCache[$value] = lcfirst(static::studly($value));
}
Illuminate\Database\Eloquent\Model: protected static $booted = [];
protected static $globalScopes = [];
protected static $dispatcher;
Illuminate\Filesystem\Filesystem: // No static properties at all
public function get($path) {
return file_get_contents($path); // Direct filesystem access
}Illuminate\Http\Client\Response: // No static properties
protected $decoded; // Instance-level cache only
public function json() {
if (! $this->decoded) {
$this->decoded = json_decode($this->body(), true);
}
return $this->decoded;
}Framework Comparison
Implications for Coroutine IsolationWordPressIsolation needs:
Recommended: Option 2 (GLOBALS + function statics)
LaravelIsolation needs:
Key insight: Laravel static properties are SAFE to share between coroutines Why sharing is safe:
Recommended: Option 2 (GLOBALS + function statics)
Performance ConsiderationsOption 2: GLOBALS + Function StaticsOverhead: ~0-2% application-wide Option 3: All Static Properties (if needed)Overhead: +200-400% on static property access
Why Option 3 is not justified:
References |
Beta Was this translation helpful? Give feedback.
-
|
Hi Ed, In terms of memory isolation, I haven't conducted much research or contemplation. In Swoole, there is no isolation for superglobal variables, global variables, static variables, or class static properties, nor will they be saved and restored during coroutine switching. This is consistent with the behavior of threads, as any thread can read global variables. The only difference is that threads are parallel, while coroutines are sequential. Modifying the PHP underlying code to accommodate frameworks like WordPress and Laravel is extremely difficult. If it is necessary to support WordPress and Laravel, I believe a brand-new sandbox system should be designed. This system would start a long-lived, concurrent environment through php-cli. Within this environment, PHP code would operate as a superuser, capable of managing many requests and global data simultaneously. It would create an isolated sandbox environment for the code of WordPress and Laravel, with each sandbox possessing its own set of global variables. Code sample$n = 100;
while($n--) {
new Coroutine(function () {
$sandbox = new Sandbox();
$sandbox->globalScopes = [
'_GET' = [],
'_POST' = [],
'GLOBALS' = [],
'function_table' => [
'foo' => [
'static_var' => 'hello',
],
],
'class_table' => [
'class1' => [
'static_prop' => 'test',
],
]
];
$sandbox->run('wordpress/index.php');
});
} |
Beta Was this translation helpful? Give feedback.
-
|
Memory isolation is transparent to legacy code even when the request lifecycle runtime transitions from a process to a coroutine. No changes are required, and everything will work as before, provided developers do not explicitly create coroutines. However, if developers explicitly create coroutines and wish to reuse native cache to improve efficiency, they should use a new global varible or objects expose mechanism among coroutines in a process. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
An attempt was made to modify the PHP CORE to localize static/GLOBALS variables for individual coroutines.
Results
Preliminary results.
The first simple tests show no performance difference. However, in theory, such a difference may appear under specific conditions. For example, when there are many static variables or many functions with static variables.
Problem with object static properties
The difficulty appeared when trying to localize object static properties. The Zend Engine caches access to such properties in the
runtime_cache, which is unique per function. This is similar to stack-local variables.When PHP executes a function for the first time, it allocates slots for the class’s static properties and builds an array of slots that are computed only once on first access.
Main difficulty
A single function has only one shared set of such slots. Even if the function runs in different coroutines, it still uses the same set.
In theory, to implement this mechanism, you would need to change the logic that resolves a static property from its slot through an indirect address that is coroutine-specific.
Code and tests:
https://github.com/true-async/php-src/tree/global-static-isolation
https://github.com/true-async/php-async/blob/global-static-isolation/tests/context/007-coroutine_static_isolation_multiple.phpt
https://github.com/true-async/php-async/blob/global-static-isolation/tests/context/011-coroutine_global_created_in_coro.phpt
Beta Was this translation helpful? Give feedback.
All reactions