perf(gc): increase native heap initial threshold to 16 MiB

- Updated default initial collection threshold from 10 MiB to 16 MiB
- Increased test loop iterations to accommodate new memory threshold
- Removed padding fields from native class test objects
- Adjusted gc-threshold test to allocate 1100000 objects instead of 300000
- Updated documentation to reflect new 16 MiB initial threshold value
- Modified multiple native class test files to align with new threshold settings
master
韩天峰 7 days ago
parent d1704b42ef
commit 68bdedaa31
  1. 2
      docs/NATIVE_CLASS_IMPLEMENTATION_AUDIT.md
  2. 11
      docs/NATIVE_CLASS_OBJECT.md
  3. 3
      tests/compiler/native-class/failed-clone-finalizer.phpt
  4. 3
      tests/compiler/native-class/failed-lifecycle-escape.phpt
  5. 3
      tests/compiler/native-class/finalizer-allocation.phpt
  6. 3
      tests/compiler/native-class/finalizer-inheritance-exception.phpt
  7. 9
      tests/compiler/native-class/gc-threshold.phpt
  8. 3
      tests/compiler/native-class/lifecycle-exceptions.phpt

@ -90,7 +90,7 @@
|---|---|---|---| |---|---|---|---|
| Wren 风格精确、非移动、STW mark-sweep | `phpx/thirdparty/wren-gc`、`native_gc.cc` | PHPX `wren_gc.*` | 已验证 | | Wren 风格精确、非移动、STW mark-sweep | `phpx/thirdparty/wren-gc`、`native_gc.cc` | PHPX `wren_gc.*` | 已验证 |
| 裸指针写入无 RC、无 write barrier | Native pointer field/local codegen | 生成 C++ 审查、Native PHPT | 已验证 | | 裸指针写入无 RC、无 write barrier | Native pointer field/local codegen | 生成 C++ 审查、Native PHPT | 已验证 |
| 10 MiB 初始阈值、1 MiB 下限、50% headroom | Wren GC 配置 | `wren_gc.uses_stable_native_heap_defaults` | 已验证 | | 16 MiB 初始阈值、1 MiB 下限、50% headroom | Wren GC 配置 | `wren_gc.uses_stable_native_heap_defaults` | 已验证 |
| 精确 root frame 保持对象图存活 | `NativeRootFrame`、generated root slots | PHPX root tests、`gc-cycle.phpt` | 已验证 | | 精确 root frame 保持对象图存活 | `NativeRootFrame`、generated root slots | PHPX root tests、`gc-cycle.phpt` | 已验证 |
| Fiber 非 LIFO 生命周期安全 | root frame registry | `fiber-lifetime.phpt`、`fiber-shutdown.phpt`、PHPX Fiber root tests | 已验证 | | Fiber 非 LIFO 生命周期安全 | root frame registry | `fiber-lifetime.phpt`、`fiber-shutdown.phpt`、PHPX Fiber root tests | 已验证 |
| global/static request roots 在 ZTS 下为 thread-local | generated globals/root registration | ZTS 环境下 `global-and-static.phpt`、PHPX request root tests | 已验证 | | global/static request roots 在 ZTS 下为 thread-local | generated globals/root registration | ZTS 环境下 `global-and-static.phpt`、PHPX request root tests | 已验证 |

@ -733,18 +733,19 @@ PHPX 的 Native GC adapter 负责类型 descriptor、root frame、C++ 析构回
首版采用以下固定默认值: 首版采用以下固定默认值:
- 首次收集阈值:10 MiB。 - 首次收集阈值:16 MiB。
- 收集后的最低阈值:1 MiB。 - 收集后的最低阈值:1 MiB。
- 存活堆增长比例:50%。 - 存活堆增长比例:50%。
- 下一次收集阈值:`max(1 MiB, liveBytes + liveBytes * 50%)`。 - 下一次收集阈值:`max(1 MiB, liveBytes + liveBytes * 50%)`。
这组参数沿用 Wren 的成熟默认值。阈值会随每轮收集后的实际存活字节数自动伸缩, 自适应增长策略沿用 Wren 的成熟设计;TypePHP 将首次阈值设为更规整的 16 MiB。
阈值会随每轮收集后的实际存活字节数自动伸缩,
但不读取 PHP `memory_limit`、主机物理内存或容器内存。PHP `memory_limit` 面向 但不读取 PHP `memory_limit`、主机物理内存或容器内存。PHP `memory_limit` 面向
Zend 请求内存,常见的 128 MiB 默认值不能代表常驻 TypePHP 程序的 Native Heap Zend 请求内存,常见的 128 MiB 默认值不能代表常驻 TypePHP 程序的 Native Heap
预算;按主机内存同比放大阈值也会使相同程序在不同机器上表现不稳定。 预算;按主机内存同比放大阈值也会使相同程序在不同机器上表现不稳定。
10 MiB 只表示首次触发完整收集前允许的累计 Native allocation,并不是预留或立即 16 MiB 只表示首次触发完整收集前允许的累计 Native allocation,并不是预留或立即
申请 10 MiB。1 MiB 下限避免小型存活集反复触发 stop-the-world 收集;50% headroom 申请 16 MiB。1 MiB 下限避免小型存活集反复触发 stop-the-world 收集;50% headroom
在扫描 CPU 与额外内存之间采取比 Go 默认 100% 更保守的折中,因为首版 collector 在扫描 CPU 与额外内存之间采取比 Go 默认 100% 更保守的折中,因为首版 collector
是单线程 stop-the-world,而不是并发 collector。后续只能依据 TypePHP 的真实分配率、 是单线程 stop-the-world,而不是并发 collector。后续只能依据 TypePHP 的真实分配率、
存活率、暂停时间和峰值内存 benchmark 调整这些内部常量,不开放语言级 GC 调参接口。 存活率、暂停时间和峰值内存 benchmark 调整这些内部常量,不开放语言级 GC 调参接口。
@ -1428,7 +1429,7 @@ Native Class 的主要路径必须满足:
- Native Object 永远不能转换或赋值为 Interface 类型;`implements` 只提供编译期契约 - Native Object 永远不能转换或赋值为 Interface 类型;`implements` 只提供编译期契约
校验,首版不提供调用点特化、fat pointer 或 interface table。 校验,首版不提供调用点特化、fat pointer 或 interface table。
- Native Heap 使用 10 MiB 首次阈值、1 MiB 最低阈值和 50% live-heap headroom。 - Native Heap 使用 16 MiB 首次阈值、1 MiB 最低阈值和 50% live-heap headroom。
这些约定已经固定。后续 benchmark 可以调整 GC 的内部数值,但不得改变 Native Object 这些约定已经固定。后续 benchmark 可以调整 GC 的内部数值,但不得改变 Native Object
不做 Interface 类型擦除、没有 Zend 表示、热路径使用裸指针 Native Call 的基本设计。 不做 Interface 类型擦除、没有 Zend 表示、热路径使用裸指针 Native Call 的基本设计。

@ -25,12 +25,11 @@ class NativeFailedCloneFinalizer
class NativeFailedClonePressure class NativeFailedClonePressure
{ {
public int $value; public int $value;
public int $padding;
} }
function forceFailedCloneCollection(): void function forceFailedCloneCollection(): void
{ {
for ($i = 0; $i < 400000; $i++) { for ($i = 0; $i < 800000; $i++) {
new NativeFailedClonePressure(); new NativeFailedClonePressure();
} }
} }

@ -68,12 +68,11 @@ class NativeFailedCloneEscape
class NativeFailedLifecyclePressure class NativeFailedLifecyclePressure
{ {
public int $value; public int $value;
public int $padding;
} }
function forceNativeCollection(): void function forceNativeCollection(): void
{ {
for ($i = 0; $i < 400000; $i++) { for ($i = 0; $i < 800000; $i++) {
$filler = new NativeFailedLifecyclePressure(); $filler = new NativeFailedLifecyclePressure();
} }
} }

@ -28,7 +28,6 @@ class NativeFinalizerCreator
class NativeFinalizerFiller class NativeFinalizerFiller
{ {
public int $value; public int $value;
public int $padding;
} }
function main(): void function main(): void
@ -39,7 +38,7 @@ function main(): void
$creator = new NativeFinalizerCreator(); $creator = new NativeFinalizerCreator();
$creator = null; $creator = null;
for ($i = 0; $i < 400000; $i++) { for ($i = 0; $i < 800000; $i++) {
$filler = new NativeFinalizerFiller(); $filler = new NativeFinalizerFiller();
} }

@ -28,12 +28,11 @@ class NativeThrowingFinalizerChild extends NativeThrowingFinalizerBase
class NativeFinalizerPressureObject class NativeFinalizerPressureObject
{ {
public int $value; public int $value;
public int $padding;
} }
function collectThrowingFinalizer(): void function collectThrowingFinalizer(): void
{ {
for ($i = 0; $i < 400000; $i++) { for ($i = 0; $i < 800000; $i++) {
try { try {
$filler = new NativeFinalizerPressureObject(); $filler = new NativeFinalizerPressureObject();
} catch (RuntimeException $error) { } catch (RuntimeException $error) {

@ -6,12 +6,6 @@ Native class: long-running allocation triggers automatic tracing collection
#[Native] #[Native]
class NativeGcThresholdValue class NativeGcThresholdValue
{ {
// Keep the pressure in the object payload so this test does not depend on
// the implementation size of the hidden Native GC header.
public int $padding1;
public int $padding2;
public int $padding3;
public function __destruct() public function __destruct()
{ {
global $nativeGcFinalized; global $nativeGcFinalized;
@ -23,7 +17,8 @@ function main(): void
{ {
global $nativeGcFinalized; global $nativeGcFinalized;
$nativeGcFinalized = 0; $nativeGcFinalized = 0;
for ($i = 0; $i < 300000; $i++) { // Allocate enough compact objects to cross the default 16 MiB threshold.
for ($i = 0; $i < 1100000; $i++) {
$value = new NativeGcThresholdValue(); $value = new NativeGcThresholdValue();
} }
var_dump($nativeGcFinalized > 0); var_dump($nativeGcFinalized > 0);

@ -66,13 +66,12 @@ class NativeThrowingFinalizer
class NativeLifecycleFiller class NativeLifecycleFiller
{ {
public int $value; public int $value;
public int $padding;
} }
function allocateUntilFinalizerRuns(): void function allocateUntilFinalizerRuns(): void
{ {
global $nativeFinalizers; global $nativeFinalizers;
for ($i = 0; $i < 400000; $i++) { for ($i = 0; $i < 800000; $i++) {
try { try {
$filler = new NativeLifecycleFiller(); $filler = new NativeLifecycleFiller();
} catch (RuntimeException $error) { } catch (RuntimeException $error) {

Loading…
Cancel
Save