Yii内存偏高主因是调试模式、AR实例、日志及缓存配置不当;应关闭YII_DEBUG和debug模块,优先使用asArray(),预加载关系,用Redis替代FileCache,精简AssetBundle,并清理缓存。

Yii 应用内存占用偏高,通常不是框架本身“吃得多”,而是缓存、AR 实例、日志、未释放的资源或配置不当导致的。关键得看 memory_get_peak_usage() 报出的实际峰值,再针对性切掉冗余开销。
关闭调试模式并禁用调试工具栏
开发时开着 YII_DEBUG=true 和 yii\debug\Module,每个请求都会记录 SQL、堆栈、变量快照——这会额外吃掉 2–5MB 内存,且不释放。生产环境必须关死:
-
defined('YII_DEBUG') or define('YII_DEBUG', false);放在web/index.php顶部 - 从
config/web.php的modules配置里彻底移除'debug' => 'yii\debug\Module' - 确认没在任意地方手动调用
Yii::getLogger()->flush()或开启 trace 级别日志
限制 ActiveRecord 实例化与 asArray() 优先
ActiveRecord 对象比纯数组多出大量元数据(属性定义、事件监听器、关系缓存等)。查 1000 条记录时,Post::find()->all() 可能占 8MB,而 Post::find()->asArray()->all() 常压到 2MB 以内:
- API 接口、导出逻辑、后台列表页——只要不调用
$model->save()或访问虚拟属性,一律加->asArray() - 避免在循环中反复调用
$model->getRelation(),改用->with()预加载后统一处理 - 批量更新不用 AR:直接用
Post::updateAll(['status' => 1], ['id' => $ids]),跳过对象构造
调整缓存组件与 Schema 缓存生命周期
缓存本身省 IO,但用错方式反而增内存:Redis 缓存实例若未设 keyPrefix 或过期策略,可能堆积无效键;Schema 缓存若指向文件缓存(FileCache),每次刷新都写临时文件并 hold in memory:
- 强制使用
yii\redis\Cache替代FileCache,并在components.cache中指定'keyPrefix' => 'myapp_prod_' - 确保
db.enableSchemaCache = true,且db.schemaCache = 'cache'指向同一个 Redis 缓存实例(避免多缓存源分裂) - 如果用 APCu,确认
apc.enable_cli=0(CLI 场景下 APCu 不共享内存,会导致重复缓存)
清理未使用的 AssetBundle 与禁用冗余 CSS/JS
AssetBundle 默认注册全量依赖,比如 yii\bootstrap\BootstrapAsset 会引入整套 Bootstrap CSS,哪怕页面只用一个按钮:
- 在
config/web.php的assetManager.bundles中禁用不需要的资源:'yii\bootstrap\BootstrapAsset' => ['css' => [], 'js' => []] - 按页面拆分 AssetBundle(如
CheckoutAsset),只注册当前页真正需要的 JS/CSS - 检查是否误将
AppAsset注册在 layout 里,又在子视图里重复注册——用AssetBundle::register($this)前先确认是否已注册
内存问题最常被忽略的是“缓存没清干净”和“AR 模型被无意复用”。上线前跑一次 php yii cache/flush-all,再用 memory_get_peak_usage(true) 在关键 Action 里打点,比盲目调 memory_limit 有用得多。


















