※当サイトの記事には、広告・プロモーションが含まれます。

Windowsの.batファイルで小数点の計算ができないという罠

xtech.nikkei.com

⇧ amazing...

Windowsの.batで小数点の計算ができないという罠

見事に泥沼にハマった...

何か、Javaのjstatで収集されたデータ(拡張子は「.tsv」のファイル。タブ区切りになっている)から、

  • 平均値
  • 最大値
  • 最小値

を計算する処理をWindowsの「.bat」ファイルとかで実現できるんかな?って思って実装を進めていて、いよいよ計算するところまで来たら、まさかの小数点の計算に対応していないということが発覚...

Microsoftさん、やってくれたやないか...

2023年10月23日(月)追記:↓ ここから

ネットの情報をググっていたら、

inamori.hateblo.jp

バッチファイルでは本来整数演算しかできないのですが、IEEE754の単精度をエミュレートすることにより浮動小数点数演算を実現します。Project Euler 25が解ければいいので、厳密にエミュレートはしません。

バッチファイルで浮動小数点数演算(1) - inamori’s diary

IEEE754の単精度は、簡単に言うと仮数部を23ビット、指数部を8ビット、符号を1ビットで表します。これをつなげて32ビットの整数とします。例えば、リンク先の0.15625は0x3E200000となります。整数とすることで、exit /bで関数から値を返すことができます。そうするとsetlocalが使えて安全にプログラミングすることができます。

バッチファイルで浮動小数点数演算(1) - inamori’s diary

⇧ 小数点を含む計算を実現してる強強エンジニアがおられました。頑張ればできるっぽいです。と言うか、バッチファイルで用意されていないデータ型を、IEEE754の仕様を実現してデータ型を実現させるって天才やん...

2023年10月23日(月)追記:↑ ここまで

というわけで、どうしても、Windows標準の機能しか利用できない環境であるなら、PowerShellとか使っていった方が良いってことなんですかね...

何やら、PowerShellなら

qiita.com

Excelへの転記とかも自動化できるっぽい。

話を戻すと、Windowsの「.bat」ファイルのスクリプトが計算時に小数点が考慮できない仕様なので使い物にならないけど、一応、ソースコードを晒します。

■C:\Users\Toshinobu\Desktop\soft_work\winodws_work\work_bat\calc_max_and_min_and_avg_per_file.bat

@echo off

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 変数定義
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
setlocal enabledelayedexpansion

rem ログファイル名
set log_file=result_calc.txt

rem 改行コードを変数として宣言、初期化
rem ※改行コードを変数として宣言、初期化した場合、2行分のスペースが必須
set LF=^


rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 処理開始
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

rem 処理の開始時間
set start_date=%date%
call :getStartTime
echo 【処理開始日時】%start_date% %T% >> %log_file%

rem メイン処理を実行
echo 【start】main
call :main
echo 【finish】main

call :onError

rem 処理の終了時間
set finish_date=%date%
call :getEndTime
echo 【処理終了日時】%finish_date% %T1% >> %log_file%

rem 処理時間を計算
call :calcProcessingTime
call :putTime
echo 【処理時間】%processing_time% >> %log_file%

exit /b

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 処理終了
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ メインの処理
rem ■ 【引数】
rem ■    なし
rem ■ 【戻り値】
rem ■    @return %errorlevel%
rem ■      0:     正常終了
rem ■      0以外:異常終了(何かしらエラー)
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:main

    set /a times_10=10
    set /a unit_byte_MB=1024

    rem jstatの「-gc オプション」で取得できる項目一覧を出力する処理を実行
    call :echoListJstatJava11 >> %log_file%
    
    echo 【start】ファイル読み込み
    for /r %1 %%i in (*.tsv) do (
        set /a count=0
        set /a sum=0
        set max=0
        set min=2147483647

        set file_path=%%i
        set /a count+=1
        echo 【!count!ファイル目】!file_path!
        call :processFile "%%i"

        call :writeResultCalc
    )
    echo 【finish】ファイル読み込み

exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ ファイル読み込み
rem ■ 最大値、最小値の算出も実施
rem ■ 【引数】【外部】
rem ■    ディレクトリのパス
rem ■ 【戻り値】
rem ■    @return %errorlevel%
rem ■      0:     正常終了
rem ■      0以外:異常終了(何かしらエラー)
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ファイル読み込み
rem 最大値、最小値の算出も実施
:processFile

    echo 【start】:processFile
    echo 【引数】%1

    set header_read=false
    set /a row_index=0

    rem 行の数だけ繰り返し
    for /f "usebackq delims=" %%r in (%1) do (
        
        echo 【start】!row_index!行目
        
        set line[!row_index!]=%%r
        set /a column_index=0

        rem 列の数だけ繰り返し
        for %%c in (%%r) do (
            set col[!row_index!][!column_index!]=%%c
            set /a column_index=!column_index!+1
        )
               
        if !header_read! == false (
           echo 【ヘッダー】

           set header_read=true
           set header=【!col[0][2]!+!col[0][3]!+!col[0][5]!+!col[0][7]!】
           echo !header!

        ) else (
           echo 【ヘッダー以外】

           rem 小数点の対策で、10倍
           set /a current_S0U=col[!row_index!][2]*times_10
           set /a current_S1U=col[!row_index!][3]*times_10
           set /a current_EU=col[!row_index!][5]*times_10
           set /a current_0U=col[!row_index!][7]*times_10

           call echo %!%col[!row_index!][2]%!%=%%current_S0U%%
           call echo %!%col[!row_index!][3]%!%=%%current_S1U%%
           call echo %!%col[!row_index!][5]%!%=%%current_EU%%
           call echo %!%col[!row_index!][7]%!%=%%current_0U%%

           rem 1行分の合計
           set /a sum_per_row=current_S0U+current_S1U+current_EU+current_0U
           echo 【SUM_PER_ROW】!sum_per_row!          

           rem すべての行の合計
           set /a sum+=sum_per_row
           echo 【SUM】!sum!
           call :updateMax !current_S0U! !current_S1U! !current_EU! !current_0U!
           call :updateMin !current_S0U! !current_S1U! !current_EU! !current_0U!

           rem 行数をインクリメント
           rem (ヘッダー行は行数としてカウントしない)
           set /a row_index=!row_index!+1
        )

    )

    rem 平均値を算出
    set /a avg=!sum!/!row_index!
    echo 【SUM】!sum!/【行数】!row_index!
    echo 【AVG】!avg!
    echo 【finish】:processFile
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 計算結果をファイルに書き込む処理
rem ■ 【引数】
rem ■    なし
rem ■ 【戻り値】
rem ■    @return %errorlevel%
rem ■      0:     正常終了
rem ■      0以外:異常終了(何かしらエラー)
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:writeResultCalc
    echo 【start】writeResultCalc
    echo 【処理開始】最大値、最小値、平均値の算出
    if %count% equ 0 (
        echo No data found.

    ) else (

        echo 【対象ファイル】!file_path!  >> %log_file%
        echo 【jstat取得項目】!header!  >> %log_file%

        echo 【MAX】!max!
        echo 【MIN】!min!
        echo 【AVG】!avg!

        set /a result_max=!max!/times_10/unit_byte_MB
        echo 【最大値】Max: !result_max! >> %log_file%
        set /a result_min=!min!/times_10/unit_byte_MB
        echo 【最小値】Min: !result_min! >> %log_file%
        set /a result_avg=!avg!/times_10/unit_byte_MB
        echo 【平均値】Avg: !result_avg! >> %log_file%
    )
    echo 【finish】writeResultCalc
    echo 【処理終了】最大値、最小値、平均値の算出
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 最大値を算出する処理
rem ■ 【引数】
rem ■    @param S0U:	Survivor領域0の使用率(KB)
rem ■    @param S1U:	Survivor領域1の使用率(KB)
rem ■    @param EU:	Eden領域の使用率(KB)
rem ■    @param OU:	Old領域の使用率(KB)
rem ■ 【戻り値】
rem ■    @return %errorlevel%
rem ■      0:     正常終了
rem ■      0以外:異常終了(何かしらエラー)
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:updateMax
    echo 【start】:updateMax
    echo 【引数】%1 %2 %3 %4
    set /a value_max=%1^
       +%2^
       +%3^
       +%4

    echo 【:updateMax】【MAX】!min!
    echo 【:updateMax】【S0U+S1U+EU+OU】!value_max!
    if !value_max! gtr !max! (
        set /a max=!value_max!
    )
    echo 【CURRENT】【MAX】!max!
    echo 【finish】:updateMax 
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 最小値を算出する処理
rem ■ 【引数】
rem ■    @param S0U:	Survivor領域0の使用率(KB)
rem ■    @param S1U:	Survivor領域1の使用率(KB)
rem ■    @param EU:	Eden領域の使用率(KB)
rem ■    @param OU:	Old領域の使用率(KB)
rem ■ 【戻り値】
rem ■    @return %errorlevel%
rem ■      0:     正常終了
rem ■      0以外:異常終了(何かしらエラー)
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:updateMin
    echo 【start】:updateMin
    echo 【引数】%1 %2 %3 %4
    set /a value_min=%1^
       +%2^
       +%3^
       +%4

    echo 【:updateMin】【MIN】!min!
    echo 【:updateMin】【S0U+S1U+EU+OU】!value_min!
    if !value_min! lss !min! (
        set /a min=!value_min!
    )
    echo 【CURRENT】【MIN】!min!
    echo 【finish】:updateMin
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ jstatの「-gc オプション」で取得できる項目一覧を出力する処理
rem ■ ※Java 8のjstatの「-gc オプション」で取得できる項目の全量
rem ■ 【引数】
rem ■    なし
rem ■ 【戻り値】
rem ■    @return %errorlevel%
rem ■      0:     正常終了
rem ■      0以外:異常終了(何かしらエラー)
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:echoListJstatJava8
    echo 【start】:echoListJstatJava8
    set list_jstat_gc_option=■jstatの「-gc オプション」で取得できる項目一覧!LF!^
        列	説明!LF!^
        S0C	Survivor 領域 0 の現在の容量 (KB)!LF!^
        S1C	Survivor 領域 1 の現在の容量 (KB)!LF!^
        S0U	Survivor 領域 0 の使用率 (KB)!LF!^
        S1U	Survivor 領域 1 の使用率 (KB)!LF!^
        EC	Eden 領域の現在の容量 (KB)!LF!^
        EU	Eden 領域の使用率 (KB)!LF!^
        OC	Old 領域の現在の容量 (KB)!LF!^
        OU	Old 領域の使用率 (KB)!LF!^
        PC	Permanent 領域の現在の容量 (KB)!LF!^
        PU	Permanent 領域の使用率 (KB)!LF!^
        YGC	若い世代の GC イベント数!LF!^
        YGCT	若い世代のガベージコレクション時間!LF!^
        FGC	フル GC イベント数!LF!^
        FGCT	フルガベージコレクション時間!LF!^
        GCT	ガベージコレクション総時間

    echo !list_jstat_gc_option!
    echo 【finish】:echoListJstatJava8
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ jstatの「-gc オプション」で取得できる項目一覧を出力する処理
rem ■ ※Java 11のjstatの「-gc オプション」で取得できる項目の全量
rem ■ 【引数】
rem ■    なし
rem ■ 【戻り値】
rem ■    @return %errorlevel%
rem ■      0:     正常終了
rem ■      0以外:異常終了(何かしらエラー)
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:echoListJstatJava11
    echo 【start】:echoListJstatJava11
    set list_jstat_gc_option=■jstatの「-gc オプション」で取得できる項目一覧!LF!^
        列	説明!LF!^
        S0C:	Survivor領域0の現在の容量(KB)。!LF!^
        S1C:	Survivor領域1の現在の容量(KB)。!LF!^
        S0U:	Survivor領域0の使用率(KB)。!LF!^
        S1U:	Survivor領域1の使用率(KB)。!LF!^
        EC:	Eden領域の現在の容量(KB)。!LF!^
        EU:	Eden領域の使用率(KB)。!LF!^
        OC:	Old領域の現在の容量(KB)。!LF!^
        OU:	Old領域の使用率(KB)。!LF!^
        MC:	メタスペースのコミット済サイズ(KB)。!LF!^
        MU:	メタスペースの使用率(KB)。!LF!^
        CCSC:	圧縮されたクラスのコミット済サイズ(KB)。!LF!^
        CCSU:	使用されている圧縮されたクラス領域(KB)。!LF!^
        YGC:	Young世代のガベージ・コレクション(GC)イベントの数。!LF!^
        YGCT:	Young世代のガベージ・コレクション時間。!LF!^
        FGC:	フルGCイベントの数。!LF!^
        FGCT:	フル・ガベージ・コレクションの時間。!LF!^
        GCT:	ガベージ・コレクションの総時間。

    echo !list_jstat_gc_option!
    echo 【finish】:echoListJstatJava11
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ エラーチェック
rem ■ 【引数】
rem ■    @param %errorlevel%
rem ■      0:     正常終了
rem ■      0以外:異常終了(何かしらエラー)
rem ■ 【戻り値】
rem ■    @return %errorlevel%
rem ■      0:     正常終了
rem ■      0以外:異常終了(何かしらエラー)
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:onError
    echo 【start】:onError
    if not %errorlevel% == 0 (
        echo 【ErrorCode】[%errorlevel%]
        echo エラーがありました。[%errorlevel%] >> %log_file%
    ) else (
        echo 【ErrorCode】[%errorlevel%]
        echo エラーはありませんでした。[%errorlevel%] >> %log_file%      
    )
    echo 【finish】:onError
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 処理開始時刻
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:getStartTime
    rem 開始時刻の取得
    set T=%TIME: =0%
    set H=%T:~0,2%
    set M=%T:~3,2%
    set S=%T:~6,2%
    set C=%T:~9,2%

    rem 先頭が0の数値が8進数として扱われないようにするための処理
    set /a H=1%H%-100,M=1%M%-100,S=1%S%-100,C=1%C%-100
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 処理終了時刻
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:getEndTime
    rem 終了時刻の取得
    set T1=%TIME: =0%
    set H1=%T1:~0,2%
    set M1=%T1:~3,2%
    set S1=%T1:~6,2%
    set C1=%T1:~9,2%

    rem 先頭が0の数値が8進数として扱われないようにするための処理
    set /a H1=1%H1%-100,M1=1%M1%-100,S1=1%S1%-100,C1=1%C1%-100
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 処理時間の計算
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:calcProcessingTime
    rem 処理時間の計算
    set /a H2=H1-H,M2=M1-M
    if %M2% LSS 0 set /a H2=H2-1,M2=M2+60
     set /a S2=S1-S
    if %S2% LSS 0 set /a M2=M2-1,S2=S2+60
    set /a C2=C1-C
    if %C2% LSS 0 set /a S2=S2-1,C2=C2+100
    if %C2% LSS 10 set C2=0%C2%
exit /b 0

rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
rem ■ 処理時間の表示
rem ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
:putTime
    rem 開始・終了時刻と処理時間の表示
    rem Hが時、Mが分、Sが秒、Cがコンマ以下2桁秒
    rem 処理時間表示は適宜必要な単位のみ残して削除可

    echo 開始時刻:%T%
    echo 終了時刻:%T1%
    echo 処理時間:%H2%h %M2%m %S2%.%C2%s
    set processing_time=%H2%h %M2%m %S2%.%C2%s
exit /b 0

⇧ ちなみに、JavaJavadocを真似て、@paramとか@returnとかコメントアウトで記載しているけど、Windowsの「.bat」ファイルのスクリプトの本来の作法が全く分からんです...

そもそも、Windowsの「.bat」ファイルのスクリプトの処理では「戻り値」は、数値しか返すことができないっぽい...

あとは、関数の結果を関数の外に反映させたい場合は、グローバル変数を変更する感じになるっぽい...

で、インプットは、以下に配置していて、

中身は、

	S0C	S1C	S0U	S1U	EC	EU	OC	OU	MC	MU	CCSC	CCSU	YGC	YGCT	FGC	FGCT	GCT
2560.0	2560.0	0.0	2540.1	15872.0	9292.4	42496.0	14760.7	8192.0	7699.9	1024.0	857.7	3	0.055	0	0.000	0.055
2560.0	2560.0	2556.1	0.0	31744.0	3724.5	42496.0	16236.7	8192.0	7758.2	1024.0	857.7	4	0.064	0	0.000	0.064
2560.0	2560.0	2556.1	0.0	31744.0	12415.1	42496.0	16236.7	8192.0	7758.2	1024.0	857.7	4	0.064	0	0.000	0.064
2560.0	2560.0	2556.1	0.0	31744.0	23285.4	42496.0	16236.7	8192.0	7758.2	1024.0	857.7	4	0.064	0	0.000	0.064

	S0C	S1C	S0U	S1U	EC	EU	OC	OU	MC	MU	CCSC	CCSU	YGC	YGCT	FGC	FGCT	GCT
2560.0	2560.0	0.0	2540.1	15872.0	9292.4	42496.0	14760.7	8192.0	7699.9	1024.0	857.7	3	0.055	0	0.000	0.055
2560.0	2560.0	2556.1	0.0	31744.0	3724.5	42496.0	16236.7	8192.0	7758.2	1024.0	857.7	4	0.064	0	0.000	0.064
2560.0	2560.0	2556.1	0.0	31744.0	12415.1	42496.0	16236.7	8192.0	7758.2	1024.0	857.7	4	0.064	0	0.000	0.064
2560.0	2560.0	2556.1	0.0	31744.0	23285.4	42496.0	16236.7	8192.0	7758.2	1024.0	857.7	4	0.064	0	0.000	0.064
13824.0	2560.0	0.0	2540.1	31744.0	1870.4	42496.0	16284.7	8448.0	7761.5	1024.0	857.7	5	0.070	0	0.000	0.070
13824.0	2560.0	0.0	2540.1	31744.0	8323.1	42496.0	16284.7	8448.0	7761.5	1024.0	857.7	5	0.070	0	0.000	0.070
13824.0	2560.0	0.0	2540.1	31744.0	8323.1	42496.0	16284.7	8448.0	7761.5	1024.0	857.7	5	0.070	0	0.000	0.070
13824.0	2560.0	0.0	2540.1	31744.0	8323.1	42496.0	16284.7	8448.0	7761.5	1024.0	857.7	5	0.070	0	0.000	0.070
13824.0	2560.0	0.0	2540.1	31744.0	8323.1	42496.0	16284.7	8448.0	7761.5	1024.0	857.7	5	0.070	0	0.000	0.070
13824.0	2560.0	0.0	2540.1	31744.0	8323.1	42496.0	16284.7	8448.0	7761.5	1024.0	857.7	5	0.070	0	0.000	0.070

⇧ という感じ。で、引数ありで「.bat」ファイルを実行する。

calc_max_and_min_and_avg_per_file.bat "[対象のディレクトリ]"    

⇧ ファイルが出力され、中身を確認。

【処理開始日時】2023/10/22 16:54:52.66 
【start】:echoListJstatJava11
■jstatの「-gc オプション」で取得できる項目一覧
        列	説明
        S0C:	Survivor領域0の現在の容量(KB)。
        S1C:	Survivor領域1の現在の容量(KB)。
        S0U:	Survivor領域0の使用率(KB)。
        S1U:	Survivor領域1の使用率(KB)。
        EC:	Eden領域の現在の容量(KB)。
        EU:	Eden領域の使用率(KB)。
        OC:	Old領域の現在の容量(KB)。
        OU:	Old領域の使用率(KB)。
        MC:	メタスペースのコミット済サイズ(KB)。
        MU:	メタスペースの使用率(KB)。
        CCSC:	圧縮されたクラスのコミット済サイズ(KB)。
        CCSU:	使用されている圧縮されたクラス領域(KB)。
        YGC:	Young世代のガベージ・コレクション(GC)イベントの数。
        YGCT:	Young世代のガベージ・コレクション時間。
        FGC:	フルGCイベントの数。
        FGCT:	フル・ガベージ・コレクションの時間。
        GCT:	ガベージ・コレクションの総時間。
【finish】:echoListJstatJava11
【対象ファイル】C:\Users\Toshinobu\Desktop\soft_work\winodws_work\work_bat\【テスト結果】2023-10-21-jstat\test_01\jstat_Test.tsv  
【jstat取得項目】【S0U+S1U+EU+OU】  
【最大値】Max: 41 
【最小値】Min: 21 
【平均値】Avg: 29 
【対象ファイル】C:\Users\Toshinobu\Desktop\soft_work\winodws_work\work_bat\【テスト結果】2023-10-21-jstat\test_01\jstat_TestJvmOption.tsv  
【jstat取得項目】【S0U+S1U+EU+OU】  
【最大値】Max: 41 
【最小値】Min: 20 
【平均値】Avg: 27 
エラーはありませんでした。[0]       
【処理終了日時】2023/10/22 16:54:53.68 
【処理時間】0h 0m 1.02s 

⇧ 一応、平均値、最大値、最小値の計算はできていそう、ただ、小数点を計算できないので意味が無いのだけど...


他にも、参考にさせていただいたサイトが山ほどありましたが、以下、主な参考サイト様。

■遅延環境変数について

qiita.com

qiita.com

■時間の計算について

qiita.com

rikutoto.blogspot.com

■call echoについて

qiita.com

jak-san.hatenablog.com

■配列について

kbn48.com

meltingrabbit.com

■二次元配列について

qiita.com

commandprompt.noyokan.com

jj-blues.com

■関数について

itsakura.com

■exitとexit /bの違いについて

tecsingularity.com

■関数の戻り値について

arkgame.com

Microsoftの公式のドキュメント

learn.microsoft.com

learn.microsoft.com

とりあえず、Microsoftの公式のドキュメントに載っていない情報が多過ぎるんよな...

結論としては、小数点などを考慮した計算に対応していないので、Windowsの標準の環境しか利用できなくて、小数点を含む計算が必要な場合は、PowerShellを使わざるを得ないかと。(つまり、今回のように「.bat」ファイルでのスクリプトは利用してはならない)

まぁ、Windowsの「.batファイル」のわけ分からな過ぎる記述の仕方も相まって、.batを使う気になれないってのが一番大きいんだが、Windowsの「.batファイル」は極力使いたくないですかね...

ちょっとしたスクリプトが必要だとしても、何か他のプログラミング言語をインストールして、スクリプトを組みたいところですな...

あと、Windowsの「.bat」ファイルのスクリプトに関係ないんだけど、Javaのjstatで取得できる項目が、

で異なるとかも、jstatが試験的な機能だからなんかね?何か、Javaのバージョンで「GC(Garbage Collection)」が変わってるってのも影響してるんかね?

そもそも、Javaって、C言語みたいに煩わしいメモリの管理を気にしなくて済むように「GC(Garbage Collection)」とか導入されてるんじゃないのか?

情報科学を専門に勉強したことないから知らんけど...

また不毛な調査に時間を浪費してしまったではないか...

何て言うか、貴重な時間を返して欲しい...

毎度モヤモヤ感が半端ない...

今回はこのへんで。