PS D:\dev\container\tomcat9\bin> more .\setenv.bat
@echo off
set "CATALINA_OPTS=-Xlog:gc*:file=d:\dev\runtime\logs\gc.log:time,uptime,level,tags:filecount=60"
D:\dev\container\tomcat9\bin>startup.bat
Using CATALINA_BASE: "D:\dev\container\tomcat9"
Using CATALINA_HOME: "D:\dev\container\tomcat9"
Using CATALINA_TMPDIR: "D:\dev\container\tomcat9\temp"
Using JRE_HOME: "D:\dev\runtime\java\jdk\jdk-17.0.14"
Using CLASSPATH: "D:\dev\container\tomcat9\bin\bootstrap.jar;D:\dev\container\tomcat9\bin\tomcat-juli.jar"
Using CATALINA_OPTS: "-Xlog:gc*:file=d:\dev\runtime\logs\gc.log:time,uptime,level,tags:filecount=60"
jcmd.exe -l
PS D:\dev\container\tomcat9-1\bin> jcmd.exe -l
22212 jdk.jcmd/sun.tools.jcmd.JCmd -l
5516 org.apache.catalina.startup.Bootstrap start
7804 org.apache.catalina.startup.Bootstrap start
プロセスを見つける。複数のtomcatが動いている場合は
# Bootstrapを含むJavaプロセスをすべて取得
$tomcatProcesses = Get-CimInstance Win32_Process | Where-Object {
$_.CommandLine -like "*org.apache.catalina.startup.Bootstrap*"
}
【実行例】
PS D:\dev\container\tomcat9-1\bin> $tomcatProcesses
ProcessId Name HandleCount WorkingSetSize VirtualSize
--------- ---- ----------- -------------- -----------
7804 java.exe 526 122044416 15080996864
5516 java.exe 532 121135104 15085416448
jcmd.exe
PS D:\dev\container\tomcat9-1\bin> $tomcatProcesses
ProcessId Name HandleCount WorkingSetSize VirtualSize
--------- ---- ----------- -------------- -----------
7804 java.exe 526 122044416 15080996864
5516 java.exe 532 121135104 15085416448
PS D:\dev\container\tomcat9-1\bin> $tomcatProcesses[0].ProcessId
7804
PS D:\dev\container\tomcat9\bin> jcmd.exe $tomcatProcesses[0].ProcessId help
7804:
The following commands are available:
Compiler.CodeHeap_Analytics
~省略~
VM.log
~省略~
For more information about a specific command use 'help <command>'.
PS D:\dev\container\tomcat9-1\bin> $tomcatProcesses[0] | select-object *
ProcessName : java.exe
Handles : 526
VM : 15080996864
WS : 122044416
Path : D:\dev\runtime\java\jdk\jdk-17.0.14\bin\java.exe
Caption : java.exe
Description : java.exe
InstallDate :
Name : java.exe
Status :
CreationClassName : Win32_Process
CreationDate : 2025/05/11 13:20:50
CSCreationClassName : Win32_ComputerSystem
CSName : FARTYOSHIPC
ExecutionState :
Handle : 7804
KernelModeTime : 18750000
OSCreationClassName : Win32_OperatingSystem
OSName : Microsoft Windows 11 Pro|C:\WINDOWS|\Device\Harddisk1\Partition3
Priority : 8
TerminationDate :
UserModeTime : 43906250
WorkingSetSize : 122044416
CommandLine : "D:\dev\runtime\java\jdk\jdk-17.0.14\bin\java.exe" -Djava.util.logging.config.file="D:\
dev\container\tomcat9\conf\logging.properties" -Djava.util.logging.manager=org.apache.ju
li.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs
=org.apache.catalina.webresources -Dsun.io.useCanonCaches=false -Xlog:gc*:file=d:\dev\ru
ntime\logs\gc.log:time,uptime,level,tags:filecount=60 -Dignore.endorsed.dirs="" -classp
ath "D:\dev\container\tomcat9\bin\bootstrap.jar;D:\dev\container\tomcat9\bin\tomcat-juli
.jar" -Dcatalina.base="D:\dev\container\tomcat9" -Dcatalina.home="D:\dev\container\tomca
t9" -Djava.io.tmpdir="D:\dev\container\tomcat9\temp" org.apache.catalina.startup.Bootstr
ap start
ExecutablePath : D:\dev\runtime\java\jdk\jdk-17.0.14\bin\java.exe
HandleCount : 526
MaximumWorkingSetSize : 1380
MinimumWorkingSetSize : 200
OtherOperationCount : 22469
OtherTransferCount : 674609
PageFaults : 100153
PageFileUsage : 678128
ParentProcessId : 21376
PeakPageFileUsage : 731348
PeakVirtualSize : 15097581568
PeakWorkingSetSize : 171044
PrivatePageCount : 694403072
ProcessId : 7804
QuotaNonPagedPoolUsage : 35
QuotaPagedPoolUsage : 467
QuotaPeakNonPagedPoolUsage : 132
QuotaPeakPagedPoolUsage : 467
ReadOperationCount : 4595
ReadTransferCount : 20574507
SessionId : 1
ThreadCount : 53
VirtualSize : 15080996864
WindowsVersion : 10.0.26100
WriteOperationCount : 154
WriteTransferCount : 23492
PSComputerName :
CimClass : root/cimv2:Win32_Process
CimInstanceProperties : {Caption, Description, InstallDate, Name...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties
jcmd.exe
PS D:\dev\container\tomcat9\bin> jcmd.exe $tomcatProcesses[0].ProcessId VM.log rotate
7804:
Command executed successfully
PS D:\dev\container\tomcat9\bin> dir D:\dev\runtime\logs\
ディレクトリ: D:\dev\runtime\logs
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2025/05/11 13:06 0 gc.log
-a---- 2025/05/11 12:47 7343 gc.log.0
-a---- 2025/05/11 12:52 2499 gc.log.00
-a---- 2025/05/11 12:52 4890 gc.log.01
-a---- 2025/05/11 12:53 0 gc.log.02
-a---- 2025/05/11 12:48 4890 gc.log.1
-a---- 2025/05/11 12:50 0 gc.log.2
-a---- 2025/05/11 12:50 0 gc.log.3
# JavaとTomcatの設定
$jdkBin = "C:\Program Files\Java\jdk-17\bin"
$gcLogRelativePath = "logs\gc.log"
$thresholdDate = (Get-Date).AddDays(-60)
$today = Get-Date -Format "yyyyMMdd"
# Bootstrapを含むJavaプロセスをすべて取得
$tomcatProcesses = Get-CimInstance Win32_Process | Where-Object {
$_.CommandLine -like "*org.apache.catalina.startup.Bootstrap*"
}
if ($tomcatProcesses.Count -eq 0) {
Write-Error "Tomcatプロセスが見つかりませんでした。"
exit 1
}
$instanceIndex = 1
foreach ($proc in $tomcatProcesses) {
$pid = $proc.ProcessId
$cmdline = $proc.CommandLine
# CATALINA_BASE を推測(-Dcatalina.base=...)
if ($cmdline -match "-Dcatalina\.base=([^\s\"]+)") {
$catalinaBase = $matches[1]
} else {
Write-Warning "CATALINA_BASE を取得できません(PID=$pid)。スキップします。"
continue
}
# ログファイルパス
$gcLogPath = Join-Path $catalinaBase $gcLogRelativePath
$backupDir = Split-Path $gcLogPath
$instanceId = "inst$instanceIndex"
$backupFile = Join-Path $backupDir ("gc_${today}_$instanceId.log")
# ローテーション実行
Write-Output "[$instanceId] jcmd $pid VM.log rotate"
& "$jdkBin\jcmd.exe" $pid "VM.log" "rotate"
Start-Sleep -Seconds 2
# ログをバックアップ
if (Test-Path $gcLogPath) {
Copy-Item -Path $gcLogPath -Destination $backupFile -Force
Write-Output "[$instanceId] GCログを $backupFile に保存しました。"
} else {
Write-Warning "[$instanceId] gc.log が存在しません。"
}
# 60日より古い gc_*.log を削除
Get-ChildItem -Path $backupDir -Filter "gc_*.log" | ForEach-Object {
if ($_.Name -match "gc_(\d{8})(?:_inst\d+)?\.log") {
$logDate = [datetime]::ParseExact($matches[1], "yyyyMMdd", $null)
if ($logDate -lt $thresholdDate) {
Remove-Item $_.FullName -Force
Write-Output "[$instanceId] 削除: $($_.Name)"
}
}
}
$instanceIndex++
}
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `\"C:\Scripts\rotate_gc_log.ps1`\""
$Trigger = New-ScheduledTaskTrigger -Daily -At 0:00
Register-ScheduledTask -TaskName "RotateGcLog" -Action $Action -Trigger $Trigger -Description "Tomcat GCログのローテーション" -User "SYSTEM" -RunLevel Highest
-ExecutionPolicy Bypass: スクリプトの実行ポリシー制限を無視(安全なスクリプトならOK)
-User "SYSTEM": サーバー起動時に自動実行可能なSYSTEMアカウントで登録
-RunLevel Highest: 管理者権限で実行