(Get-WinEvent -ListLog * -ErrorAction SilentlyContinue).ProviderNames | Sort-Object -Unique | ForEach-Object { $SourceName = $_; try { (Get-WinEvent -ListProvider $SourceName -ErrorAction SilentlyContinue).Events | ForEach-Object { $Event = $_; [PSCustomObject]@{ Source = $SourceName; EventId = $Event.Id; Description = $Event.Description } } } catch { $_ | Format-List * -Force | Out-String } } | Export-Csv -Encoding UTF8 C:/tmp/Result.csv
PostgreSQLの教育にPGliteを使う
SupabaseのPostgres-WASMだと、大量(1,000件)のINSERTができない等の問題があった。
最近PGliteがリリースされ、REPL環境もあるようなので試してみた。
- ファイルをアップロードして
\i /mnt/foobar.sql
みたいなことはできないので、まとまったSQLはすべてコピペで実行する必要がある。 - SQLの実行結果はHTML形式にフォーマットして出力される。ASCIIテキストにならないので、実行結果のコピペは面倒かも。
- 1,000件のINSERT文をコピペで実行してもエラーにならない。問題なくINSERTできているように見える。
- 統計情報はリアルタイム更新されるようだが誤差が大きい。1,000件INSERTした直後に
EXPLAIN
するとrows=98
と言われる(これはそんなもんなのか?) - 利用できるextensionはラジオボックスでの選択式。
pg_stat_statements
など性能関連のextensionは含まれていないので実行できない。 - シェルにはアクセスできないので
postgresql.conf
を編集して再起動とかもできない。
普通にSQLを実行している限りでエラーが出ていないとという意味では、純粋にSQLの確認するだけの環境としてはPostgres-WASMよりいいのかも。
SpotBugsのプラグインを作ったらそのライセンスは?
SpotBugs自体のライセンスはLGPL v2.1。
SpotBugsにはプラグイン(カスタムルール)を作る仕組みが用意されていて、AnnotationDetectorとかBytecodeScanningDetectorとかOpcodeStackDetectorとかを継承したクラスを作っておいて、findbugs.xmlに追加するとカスタムルールとして動作する。
で、このカスタムルールに適用する必要のあるライセンスって何なんだろう?という話。普通に考えるとLGPLなプログラムとリンクして動くプログラムということなので、LGPLで求められるリバースエンジニアリングの許諾さえしておけばライセンスは問わない(LGPLじゃなくてもよい)ということになると思うんだけど、実例が見当たらない。これまで見たことがあるのは「LGPLなライブラリを呼んでるプログラム」だけで、「LGPLなソフトウェアから呼ばれるプログラム」は見たことがないんだよなぁ……
SpotBugsそのもの以外でSpotBugsのプラグインを公開しているGitHubのリポジトリを検索してみた*1んだけど、OWASP Find Security Bugsくらいしか見当たらなかった。これのライセンスはLGPL v3.0。
-XX:+AlwaysPreTouchでJavaVM起動時に全ヒープを物理メモリに載せたらどれくらい起動が遅くなるの?
結論: ヒープサイズ4GBのときWindowsで2秒程度、WSLで3秒程度。ヒープサイズ1GBのときWindowsで1秒程度、WSLで0.5秒程度、起動時のオーバーヘッドが増える模様。
動機
JavaVMの起動時に-Xms
と-Xmx
に同じ値を指定しても、JavaVM起動時点でそれだけの物理メモリが確保されるわけではない、という話があります。-Xms
と-Xmx
でメモリ量を指定してJavaVMを起動した直後の状態だと、おそらくUnix系のOSならbrk(2)
かsbrk(2)
、WindowsだったらVirtualAlloc
あたりが呼ばれるので、この時点でプログラムブレークの位置は設定される*1 。だけど、JavaVMは確保したメモリすべてに触りにいくわけじゃないからその時点ではOSはページフォールトを発生させる理由がない。よってOSから見ると仮想メモリがコミットされるだけで物理メモリは割り当られてない、という動きになるわけです。
それだけでもメモリ確保の都度brk(2)
やsbrk(2)
を呼ぶ動きを抑止できるという意味で、-Xms
と-Xmx
を同じ値に設定するのはスループットを高めるには有用と思われます*2。
で、物理メモリ上に本当に領域が確保される必要はないにしても、システムのリソース設計をするときはJavaヒープが全て物理メモリに載った状態でもスワップが発生しないよう設計にしておかないと、スラッシングによる性能劣化が怖い。そういう前提でリソース設計をしてたのに、いざシステムが稼動したら設計をミスっててプロセスが仮想メモリを確保できず起動しない、という状況はテストで潰しておきたい。OSがWindowsであればOSの仕様上オーバーコミットはできないからシステム稼動中と同じようにプロセスを起動しておけばこれがテストできる*3。一方、Linuxの場合はオーバーコミットするのがOSのデフォルト設定になっているので、この目的でテストをしたければ-Xms
と-Xmx
でコミットしたメモリすべてにJavaVMが触りに行ってページフォールトを発生させないとテストができないわけです。
そのためかどうかわかりませんが、Javaには-XX:+AlwaysPreTouch
という起動オプションがあって、これを指定するとJavaVM起動時に確保したメモリ(ページ)すべてに触りに行く。ただ、もちろん全メモリに触りに行くわけなので起動時のオーバーヘッドはそれなりにかかる。じゃぁどれくらいオーバーヘッドがかかるの?というのが知りたいわけです。毎分1回起動してそれなりの時間処理をするようなプロセスで、プロセス起動時のオーバーヘッドが何十秒も増えたらそれは困るので。
以下のようなプログラムを作って、-XX:+AlwaysPreTouch
ありとなしで差を確認してみました。
import java.lang.management.ManagementFactory; import com.sun.management.OperatingSystemMXBean; public class AlwaysPreTouchTest { public static void main(String[] main) { OperatingSystemMXBean osMBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); System.out.printf("Free physical memory: %dkB\n", osMBean.getFreeMemorySize() / 1024); System.out.printf("Total Java Heap: %dkB\n", Runtime.getRuntime().totalMemory() / 1024); } }
Windowsの場合
Windowsでの結果は以下のような感じ。ヒープ4GBで-XX:+AlwaysPreTouch
を指定したときの起動時間は1秒~2秒でけっこうバラつく。
PS C:\tmp> java --version openjdk 17.0.9 2023-10-17 OpenJDK Runtime Environment Temurin-17.0.9+9 (build 17.0.9+9) OpenJDK 64-Bit Server VM Temurin-17.0.9+9 (build 17.0.9+9, mixed mode, sharing) PS C:\tmp> (Measure-Command { Invoke-Expression "java.exe -Xmx4g -Xms4g AlwaysPreTouchTest" | Out-Default }).TotalSeconds Free physical memory: 5545840kB Total Java Heap: 4194304kB 0.3735332 PS C:\tmp> (Measure-Command { Invoke-Expression "java.exe -Xmx4g -Xms4g -XX:+AlwaysPreTouch AlwaysPreTouchTest" | Out-Default }).TotalSeconds Free physical memory: 1208368kB Total Java Heap: 4194304kB 2.4802916 PS C:\tmp> (Measure-Command { Invoke-Expression "java.exe -Xmx1g -Xms1g AlwaysPreTouchTest" | Out-Default }).TotalSeconds Free physical memory: 5530976kB Total Java Heap: 1048576kB 0.1812453 PS C:\tmp> (Measure-Command { Invoke-Expression "java.exe -Xmx1g -Xms1g -XX:+AlwaysPreTouch AlwaysPreTouchTest" | Out-Default }).TotalSeconds Free physical memory: 4451272kB Total Java Heap: 1048576kB 1.2108386
WSLの場合
WSLでの結果は以下のような感じ。ヒープ4GBで-XX:+AlwaysPreTouch
を指定したときの起動時間は3秒程度で安定している。一方、ヒープ1GBのときのオーバーヘッドはなぜか生のWindowsより小さい。
satob:~$ java --version openjdk 17.0.11 2024-04-16 OpenJDK Runtime Environment (build 17.0.11+9-Ubuntu-120.04.2) OpenJDK 64-Bit Server VM (build 17.0.11+9-Ubuntu-120.04.2, mixed mode, sharing) satob:~$ time java -Xmx4g -Xms4g AlwaysPreTouchTest Free physical memory: 7498060kB Total Java Heap: 4194304kB real 0m0.091s user 0m0.090s sys 0m0.019s satob:~$ time java -Xmx4g -Xms4g -XX:+AlwaysPreTouch AlwaysPreTouchTest Free physical memory: 3159932kB Total Java Heap: 4194304kB real 0m0.472s user 0m0.201s sys 0m3.046s satob:~$ time java -Xmx1g -Xms1g AlwaysPreTouchTest Free physical memory: 7529068kB Total Java Heap: 1048576kB real 0m0.218s user 0m0.113s sys 0m0.135s satob:~$ time java -Xmx1g -Xms1g -XX:+AlwaysPreTouch AlwaysPreTouchTest Free physical memory: 6441500kB Total Java Heap: 1048576kB real 0m0.184s user 0m0.096s sys 0m0.756s
「外字」とは何か?
あるシステムの設計者に「このシステムでは外字を使いますか?」と質問したとしましょう。そのとき、「はい、使います」と答えたとして、その意味として考えられるものは……
- 私用領域のコードポイントにある文字を、正規のデータとして処理する
- Windowsの日本語IMEで、変換時に「機種依存文字」と表示される文字(「髙」など)を、正規のデータとして処理する
- Windowsの日本語IMEで、デフォルト設定では変換候補に出てこない文字(JIS第3水準・第4水準など)を、正規のデータとして処理する
- 上記のような文字を日本語IMEから入力可能にするよう、ユーザ端末をキッティングする
- 1~4のような文字を、入力データのバリデーションで明示的に弾いたり、別の文字に置き換えたりするなど、特別扱いする処理を実装している
- システムのデフォルトフォントで表示できない文字を、大規模文字セット用のフォントなどをインストールして表示可能にしている
- JIS78やJIS90で字形が変わった文字の、古い方の字形を用意している
- 旧字体(「學」とか)を新字体(「学」とか)に置き換える処理をしている
- ユーザが業務運用中にEUDC.ttfを編集する
- アプリケーションが編集したEUDC.ttfを必要とする