Closed onanying closed 5 years ago
可观察的现象是:每间隔一小段时间,立即增加2mb
该问题在 swoole v4.2.13 也有,但是表现的增涨情况为线性增加,不是每间隔一小段时间,立即增加2mb
在代码尾部加一个Swoole\Event::wait()
, 再观察
<?php
\Swoole\Runtime::enableCoroutine(true);
go(function () {
for ($i = 0; $i < 100; $i++) {
go(function () {
$pdo = new \PDO(
'mysql:host=192.168.1.150;port=3306;charset=utf8;dbname=test',
'root',
'123456',
[
\PDO::ATTR_EMULATE_PREPARES => false,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
]
);
while (true) {
$statement = $pdo->prepare("select * from `test`");
$statement->execute();
$ret = $statement->fetchAll();
var_dump(json_encode($ret));
}
});
}
});
Swoole\Event::wait();
问题依旧,10多分钟:
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
php72 96.03% 154.9 MiB / 976.5 MiB 15.87% 0 B / 0 B 347 MB / 8.58 MB 5
MacOS 下未复现, 内存稳定无波动, 我试一下Linux 你可以用宿主机观察docker容器进程的内存占用, docker stats好像有点不准
Linux (Ubuntu)下: PHP总内存一段时间后无变化, 实际内存小范围波动 top观察虚拟内存和物理内存无变化 (因为PHP有内存池)
你可以把var_dump
数据打印去掉
宿主机 top VIRT RES,和 docker stats 的值非常接近,说明 docker stats 是准的,var_dump 去掉后,增长确实慢了非常多,我再长时间测试一下,看看
<?php
\Swoole\Runtime::enableCoroutine(true);
go(function () {
for ($i = 0; $i < 100; $i++) {
go(function () {
$pdo = new \PDO(
'mysql:host=192.168.1.150;port=3306;charset=utf8;dbname=test',
'root',
'123456',
[
\PDO::ATTR_EMULATE_PREPARES => false,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
]
);
while (true) {
$statement = $pdo->prepare("select * from `test`");
$statement->execute();
$ret = $statement->fetchAll();
//var_dump(json_encode($ret));
}
});
}
});
\Swoole\Event::wait();
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
99544 root 20 0 340300 26828 8776 R 93.8 2.7 0:21.31 php
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
php72 99.79% 152.6 MiB / 976.5 MiB 15.62% 0 B / 0 B 347 MB / 8.58 MB 4
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
99544 root 20 0 340300 164732 8776 R 100.0 16.5 4:01.09 php
恒定在 152.6 MiB 了,看来是没有问题,前期增长是没到那个点。
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
php72 98.71% 152.6 MiB / 976.5 MiB 15.62% 0 B / 0 B 347 MB / 8.58 MB 4
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
99544 root 20 0 340300 164732 8776 R 89.0 16.5 9:26.64 php
@twose 我也测试了一下,如果没有加以下代码
\Swoole\Event::wait();
内存确实会缓慢增长,直到超出ini限制进程退出,这个问题能否解决?可否不调用wait,稳定内存使用。 测试环境:
swoole
Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 4.3.1
Built => Mar 14 2019 10:27:20
coroutine => enabled
epoll => enabled
eventfd => enabled
signalfd => enabled
spinlock => enabled
rwlock => enabled
sockets => enabled
openssl => LibreSSL 2.7.5
http2 => enabled
pcre => enabled
zlib => enabled
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
mysqlnd => enabled
jemalloc => enabled
async_redis => enabled
Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608
@twose 对,刚刚我又测试了,不加:
\Swoole\Event::wait();
就会一直涨。
好像是之前php的bug,最新的swoole master已经兼容
@onanying 此问题曾由 @mabu233 发现并已在master解决 Swoole下个版本(v4.3.2~master)会兼容此BUG, PHP将在7.2.17/7.3.4修复 https://github.com/php/php-src/commit/bd6eabd6591ae5a7c9ad75dfbe7cc575fa907eac
@twose \Swoole\Event::wait(); 只是把时间延长了,依然会有内存增涨问题。
<?php
\Swoole\Runtime::enableCoroutine(true);
go(function () {
for ($i = 0; $i < 100; $i++) {
go(function () {
$pdo = new \PDO(
'mysql:host=192.168.1.150;port=3306;charset=utf8;dbname=test',
'root',
'123456',
[
\PDO::ATTR_EMULATE_PREPARES => false,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
]
);
while (true) {
$statement = $pdo->prepare("select * from `test`");
$statement->execute();
$ret = $statement->fetchAll();
//var_dump(json_encode($ret));
}
});
}
});
\Swoole\Event::wait();
耐心等待,从12 分钟开始:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
113685 root 20 0 340300 63332 8776 R 86.7 6.3 12:17.49 php
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
113685 root 20 0 340300 189068 8776 R 86.7 18.9 13:23.31 php
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
113685 root 20 0 340300 225572 8776 R 83.7 22.6 14:20.62 php
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
113685 root 20 0 340300 225572 8776 R 82.4 22.6 19:38.12 php
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
113685 root 20 0 340300 225572 8776 R 86.0 22.6 21:13.19 php
环境:
代码:
使用 docker stats 检测内存情况:
刚开始
半小时后:
代码2:重用 db 对象
刚开始:
10多分钟已经:
又过了才3分钟,内存迅速增加:
可见是否重用连接,都存在该问题。