はじめに
OpenClaw は Node.js 上で動作しており、デフォルトでは V8 エンジンのヒープメモリ上限は約 1.5GB(64ビットシステム)です。OpenClaw プロセスのメモリが継続的に増加し、システムの動作が遅くなったり、OOM(Out of Memory)によってプロセスが終了されたりする場合、本記事のトラブルシューティング方法が問題の原因特定と解決に役立ちます。
一、メモリ状態の簡易判定
1.1 現在のメモリ使用量の確認
# 方法1:OpenClaw ヘルスエンドポイント経由
curl -s http://localhost:18789/health/detail | jq '.memory'
# レスポンス例:
# {
# "heapUsed": "185MB",
# "heapTotal": "256MB",
# "rss": "310MB",
# "external": "12MB"
# }
# 方法2:プロセスのメモリを直接確認
ps aux | grep openclaw | grep -v grep
# 方法3:top/htop でリアルタイム確認
top -p $(pgrep -f "openclaw up")
1.2 メモリ指標の意味
| 指標 | 意味 | 正常範囲 |
|---|---|---|
| RSS | 実際の物理メモリ使用量 | < 500MB |
| Heap Used | V8 ヒープの使用済み量 | < 300MB |
| Heap Total | V8 ヒープの総割り当て量 | < 512MB |
| External | C++ オブジェクトのメモリ | < 50MB |
Heap Used が継続的に増加し、低下しない場合は、メモリリークが存在する可能性が高いです。
二、Node.js メモリ制限の設定
2.1 最大ヒープメモリの設定
# 方法1:環境変数で設定
export NODE_OPTIONS="--max-old-space-size=512"
openclaw restart
# 方法2:設定ファイルで設定(PM2 方式)
# ecosystem.config.js
{
env: {
NODE_OPTIONS: "--max-old-space-size=512"
}
}
# 方法3:Systemd 方式
# /etc/systemd/system/openclaw.service
# Environment=NODE_OPTIONS=--max-old-space-size=512
推奨メモリ制限の設定:
| サーバーメモリ | 推奨 max-old-space-size | 説明 |
|---|---|---|
| 512MB | 256 | 低スペック VPS、設定の簡素化が必要 |
| 1GB | 384 | エントリーレベル、2-3チャネルに対応 |
| 2GB | 512 | 標準構成 |
| 4GB+ | 1024 | 十分な余裕、マルチチャネル・高同時接続に対応 |
2.2 ガベージコレクションの最適化
# GC を公開し、手動トリガーを許可
export NODE_OPTIONS="--max-old-space-size=512 --expose-gc"
# より積極的な GC 戦略(メモリを削減するがパフォーマンスへの若干の影響あり)
export NODE_OPTIONS="--max-old-space-size=512 --gc-interval=100"
三、会話履歴のクリーンアップ
会話履歴はメモリ増加の主要な原因の一つです。アクティブな各会話はメモリ上にコンテキストを保持します。
3.1 会話コンテキスト制限の設定
// ~/.config/openclaw/openclaw.json5
{
"conversation": {
// 各会話で保持する最大メッセージ数
"maxMessages": 50,
// 会話のアイドルタイムアウト(秒)、タイムアウト後にメモリをクリーンアップ
"idleTimeout": 1800,
// 最大同時会話数
"maxConcurrent": 100,
// コンテキストウィンドウ戦略:sliding(スライディングウィンドウ)または summarize(要約)
"contextStrategy": "sliding"
}
}
3.2 会話キャッシュの手動クリーンアップ
# API 経由で非アクティブな会話をすべてクリーンアップ
curl -X POST http://localhost:18789/admin/cleanup \
-H "Content-Type: application/json" \
-d '{"type": "conversations", "olderThan": "1h"}'
# サービスの再起動(メモリ上のすべての会話をクリア)
openclaw restart
3.3 定期自動クリーンアップ
# 定期クリーンアップスクリプトの作成
cat > /usr/local/bin/openclaw-cleanup.sh << 'EOF'
#!/bin/bash
curl -sf -X POST http://localhost:18789/admin/cleanup \
-H "Content-Type: application/json" \
-d '{"type": "conversations", "olderThan": "2h"}'
echo "[$(date)] 会話キャッシュのクリーンアップ完了" >> /var/log/openclaw-cleanup.log
EOF
chmod +x /usr/local/bin/openclaw-cleanup.sh
# 1時間ごとに実行
echo "0 * * * * /usr/local/bin/openclaw-cleanup.sh" | crontab -
四、メモリリークの検出
4.1 Node.js 内蔵の診断機能を使用
# 起動時にヒープスナップショット機能を有効化
export NODE_OPTIONS="--max-old-space-size=512 --heapsnapshot-signal=SIGUSR2"
openclaw restart
# メモリ増加時にヒープスナップショットを生成
kill -USR2 $(pgrep -f "openclaw up")
# スナップショットファイルは作業ディレクトリに生成され、Chrome DevTools で分析可能
# Chrome を開く -> F12 -> Memory -> スナップショットファイルをロード
4.2 メモリ増加傾向の監視
#!/bin/bash
# memory-monitor.sh として保存
# 1分ごとにメモリ使用量を記録し、傾向分析に使用
LOG_FILE="/var/log/openclaw-memory.csv"
# ヘッダーの書き込み
if [ ! -f "$LOG_FILE" ]; then
echo "timestamp,rss_kb,heap_used,heap_total" > "$LOG_FILE"
fi
while true; do
TIMESTAMP=$(date +%Y-%m-%dT%H:%M:%S)
RSS=$(ps -o rss= -p $(pgrep -f "openclaw up") 2>/dev/null)
HEALTH=$(curl -sf http://localhost:18789/health/detail 2>/dev/null)
if [ -n "$RSS" ] && [ -n "$HEALTH" ]; then
HEAP_USED=$(echo "$HEALTH" | jq -r '.memory.heapUsed')
HEAP_TOTAL=$(echo "$HEALTH" | jq -r '.memory.heapTotal')
echo "$TIMESTAMP,$RSS,$HEAP_USED,$HEAP_TOTAL" >> "$LOG_FILE"
fi
sleep 60
done
4.3 メモリリークの特徴を識別する
上記のログを分析して、メモリリークの有無を判断します:
- 正常な動作:メモリが GC 後に安定した水準に戻り、ノコギリ波状に変動する
- メモリリーク:メモリが継続的に上昇し、GC 後のベースラインも上がり続ける
- 一時的な増加:大量のスキルの読み込みや複数チャネルの接続時に一度に増加し、その後安定する
五、ヒープスナップショット分析
5.1 ヒープスナップショットの生成
# 方法1:シグナルでトリガー
kill -USR2 $(pgrep -f "openclaw up")
# スナップショットファイルは現在の作業ディレクトリに生成される
# 方法2:v8-profiler を使用(コードレベルのサポートが必要)
# 通常は開発デバッグ時に使用
5.2 Chrome DevTools での分析
- Chrome ブラウザを開く
- アドレスバーに
chrome://inspectと入力 - "Open dedicated DevTools for Node" をクリック
- Memory タブに切り替え
.heapsnapshotファイルをロード- "Retained Size" でソートし、最もメモリを占有しているオブジェクトを特定
5.3 よくあるメモリリークの原因
| リーク原因 | 特徴 | 解決方法 |
|---|---|---|
| 未クリーンアップのイベントリスナー | EventEmitter オブジェクトの増加 | removeListener を確実に行う |
| 上限なしのグローバルキャッシュ | Map/Object の継続的な増加 | キャッシュ上限と LRU 戦略を設定 |
| 未クローズの WebSocket | Socket オブジェクトの蓄積 | 切断時のクリーンアップロジックを確認 |
| 大量の会話コンテキスト | String オブジェクトの大量占有 | コンテキスト長を制限 |
| スキルプラグインのリーク | サードパーティコードの問題 | 1つずつ無効化して原因を特定 |
六、低メモリデバイスの最適化
Raspberry Pi や低スペック VPS など、メモリが限られたデバイスで OpenClaw を実行する場合、以下の設定でメモリ使用量を大幅に削減できます。
6.1 簡素化された設定
// ~/.config/openclaw/openclaw.json5 - 低メモリ最適化版
{
"conversation": {
"maxMessages": 20,
"idleTimeout": 600,
"maxConcurrent": 20,
"contextStrategy": "sliding"
},
"skills": {
// 必要なスキルのみ読み込み
"autoLoad": false,
"whitelist": ["basic-chat"]
},
"channels": {
// 必要なチャネルのみ有効化
},
"cache": {
"maxSize": "50MB"
}
}
6.2 Swap の使用をバッファとして活用
# 1GB の swap ファイルを作成
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永続化
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# swappiness の調整(10に下げて物理メモリを優先使用)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
6.3 軽量モデルの使用
小さなモデルを選択することで、コンテキスト処理のメモリオーバーヘッドを削減できます:
{
"models": {
"primary": {
"provider": "ollama",
"model": "phi3:mini" // 約 2GB VRAM/メモリ
}
}
}
七、PM2 メモリ制限付き自動再起動
PM2 のメモリ制限機能を活用して、メモリ超過時に自動再起動を行います:
// ecosystem.config.js
module.exports = {
apps: [{
name: "openclaw",
script: "openclaw",
args: "up",
max_memory_restart: "400M",
env: {
NODE_OPTIONS: "--max-old-space-size=512"
}
}]
};
# 設定の適用
pm2 start ecosystem.config.js
# メモリ使用量と再起動回数の確認
pm2 describe openclaw | grep -E "memory|restart"
八、メモリ問題のトラブルシューティングフローチャート
メモリ過大
│
├── RSS > 500MB?
│ ├── はい → Heap Used を確認
│ │ ├── Heap Used が継続的に増加 → メモリリーク
│ │ │ ├── ヒープスナップショットを生成して分析
│ │ │ ├── スキルを1つずつ無効化して原因を特定
│ │ │ └── 会話コンテキスト制限を確認
│ │ └── Heap Used が安定 → External メモリ
│ │ └── MCP Server またはネイティブモジュールを確認
│ └── いいえ → 正常範囲内
│
└── OOM Killer に終了された?
├── swap 容量を増やす
├── --max-old-space-size を設定
├── 同時会話数を減らす
└── サーバーメモリをアップグレード
以上の方法で、OpenClaw のメモリ関連の問題の大部分を診断・解決できるはずです。メモリリークが継続する場合は、OpenClaw の GitHub リポジトリに Issue を提出し、ヒープスナップショットの分析結果を添付することをお勧めします。