Жизненный цикл
Цикл жизни процесса
- Каждый процесс имеет длительный жизненный цикл
- Каждый процесс работает независимо и не мешает другим процессам
- Каждый процесс может обрабатывать несколько запросов в течение своего жизненного цикла
- Процесс завершает текущий жизненный цикл при получении команд
stop
,reload
,restart
Подсказка
Каждый процесс является независимым, что означает, что каждый процесс поддерживает свои собственные ресурсы, переменные и экземпляры классов и т. д. Это выражается в том, что каждый процесс имеет собственное соединение с базой данных; некоторые синглтоны инициализируются один раз в каждом процессе, что приводит к многократной инициализации в нескольких процессах.
Цикл жизни запроса
- Каждый запрос генерирует объект
$request
- Объект
$request
будет освобожден после обработки запроса
Цикл жизни контроллера
- Каждый контроллер будет инициализирован только один раз в каждом процессе, но будет инициализирован много раз в нескольких процессах (кроме ситуаций с повторным использованием контроллера, см. Цикл жизни контроллера)
- Экземпляры контроллера будут совместно использоваться несколькими запросами в текущем процессе (кроме случаев с повторным использованием контроллера)
- Цикл жизни контроллера заканчивается после завершения процесса (кроме случаев с повторным использованием контроллера)
О жизни переменных
Webman разработан на основе PHP, поэтому он полностью соответствует механизму управления памятью в PHP. Временные переменные, создаваемые в бизнес-логике, включая экземпляры классов, создаваемые с помощью ключевого слова new, автоматически освобождаются после завершения функции или метода, без необходимости вручную вызывать unset
. Это означает, что опыт разработки в Webman в основном совпадает с опытом разработки в традиционных фреймах. Например, в приведенном ниже примере экземпляр $foo
будет автоматически освобожден по завершении метода index:
<?php
namespace app\controller;
use app\service\Foo;
use support\Request;
class IndexController
{
public function index(Request $request)
{
$foo = new Foo(); // Предполагается, что существует класс Foo
return response($foo->sayHello());
}
}
Если вы хотите, чтобы экземпляр какого-либо класса использовался повторно, вы можете сохранить класс в статическом свойстве класса или в свойстве объекта с длительным жизненным циклом (например, контроллер). Также можно использовать метод get контейнера для инициализации экземпляров класса, например:
<?php
namespace app\controller;
use app\service\Foo;
use support\Container;
use support\Request;
class IndexController
{
public function index(Request $request)
{
$foo = Container::get(Foo::class);
return response($foo->sayHello());
}
}
Метод Container::get()
используется для создания и сохранения экземпляра класса; если вы снова вызовете его с теми же параметрами, он вернет ранее созданный экземпляр класса.
Внимание
Container::get()
может инициализировать только экземпляры без параметров конструктора.Container::make()
может создавать экземпляры с параметрами конструктора, однако в отличие отContainer::get()
,Container::make()
не будет повторно использовать экземпляр, то есть даже с теми же параметрамиContainer::make()
всегда будет возвращать новый экземпляр.
О утечках памяти
В большинстве случаев наш бизнес-код не вызывает утечек памяти (очень редко пользователи сообщают об утечках памяти), нам просто нужно внимательно следить за тем, чтобы массивы с длительным жизненным циклом не расширялись бесконечно. Пожалуйста, посмотрите следующий код:
<?php
namespace app\controller;
use support\Request;
class FooController
{
// Свойство массива
public $data = [];
public function index(Request $request)
{
$this->data[] = time();
return response('hello index');
}
public function hello(Request $request)
{
return response('hello webman');
}
}
Контроллер по умолчанию имеет длительный жизненный цикл (за исключением случаев с повторным использованием контроллера), и массив $data
также имеет длительный жизненный цикл. Поскольку запросы к foo/index
продолжают увеличиваться, количество элементов в массиве $data
растет, что может привести к утечкам памяти.
Для получения дополнительной информации смотрите Утечка памяти