ITエンジニアの技術メモ

神奈川在住のITエンジニアの備忘録です。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

SSLサーバ証明書を生成する時の alias について

先日、Java の keytool コマンドを使用して、SSLサーバ証明書を生成しようと思ったら、コマンドの引数に指定する「-alias」オプションに何を指定して良いのか分からなくてちょっと調べたので、防備としてここにメモしておく。

「-alias」オプションには、生成しようとしている証明書の「名前」を指定する。この「名前」は、対象アプリの keystore 内で一意になるものであれば適当なもので問題ないようだ。

[参考]

https://docs.oracle.com/javase/jp/6/technotes/tools/solaris/keytool.html

https://www.toritonssl.com/support/manual/04-5.html

「仮想メモリ」について

先日、「仮想メモリ」という用語について認識が割れ、議論が噛み合わないことがあった。

一方は、いわゆる「ページング領域」や「スワップ領域」のように、HDDの一部を仮想的にメモリとして使用している領域であると認識し、もう一方は、プロセスから見える仮想メモリアドレス空間であると認識していた。

グーグル先生に「仮想メモリとは」で聞いたところ、前者の方が検索結果の上記に出てきたので、こちらの方が一般的なんだと思う。

ただ、特にOSに詳しい人とかは後者の方で認識してそうな気がするので、今後「仮想メモリ」の話が出たら、どちらの意味なのか明確にした上で話したいと思う。

文字参照を含むファイルを通常の文字列に変換して出力する

html の文字参照を含むファイルを通常の文字列に変換して出力する perl スクリプトを作成した。使い方は、perl "スクリプト名" "文字参照を含むファイル"

use strict;
use warnings;
use HTML::Entities;
use Encode;

my $file = $ARGV[0];
open(my $in,  "< $file") or die("Error :$!");

my $wholeText;
while (my $line = <$in>) {
    $wholeText .= $line;
}

$wholeText = HTML::Entities::decode_entities($wholeText);
#print encode('utf-8', $wholeText); # utf-8で出力する場合
print encode('sjis', $wholeText); # sjisで出力する場合

中身を簡単に説明すると、HTML::Entities::decode_entities() を使って、文字参照を含むファイルの中身を通常の文字列に変換して、文字コードを指定して出力している。

JavaScriptでメモリーリークするパターン

JavaScriptメモリリークするパターンについてネット上の情報から調べてみた。以下に簡単に纏める。

  • オブジェクト間で循環参照が発生し、各オブジェクトへの参照カウンタが0にならず、オブジェクトが不要になってもGC(ガベージ・コレクション)により回収されない。
  • クロージャの使用。クロージャで生成した変数に、使用後に明示的に null を代入していないと、クロージャ内部のローカル変数などが解放されない場合があるらしい。
  • デタッチされたDOMノード。
  • コンソール・ログへの出力。
  • グローバル変数の使用。

どのパターンでメモリリークするかは、ブラウザ側の実装に依存すると思うので、ブラウザの種類やバージョンによると思われる。

一般的に、クライアント側は、サーバ側に比べると長時間継続して使用されることは少ないので、そこまでメモリリークを気にしないことが多いが、一応、気を付けておきたい。

 

〇参考

デスクトップヒープの枯渇

Windowsサーバで、バックグラウンドの処理が大量に実行され、デスクトップヒープの枯渇が発生したことがあった。

デスクトップヒープのことをあまり分かっていなかったこともあり、「GUIの部品を使わないバックグラウンドの処理なのに、何故デスクトップヒープが枯渇したのか・・?」と思ったが、ちょっと調べてみたところ、以下の記事を見つけた。

デスクトップ ヒープが枯渇すると、新たなユーザー オブジェクトを作成することができなくなるため、ウィンドウなどの GUI の維持に必要なデータが配置できず、結果としてアプリケーションの起動失敗や、サービスによりバックグラウンドで実行されるバッチ処理の実行失敗につながります。

殊によくあるのが、大量のバッチ処理をサービスとして並行実行することで、デスクトップ ヒープが枯渇し、バッチ処理の実行が途中で失敗してしまうというケースです。
cmd.exe と cmd.exe に付随して起動される conhost.exe は、非対話型デスクトップ上でもそれぞれウィンドウやメニュー バー、キャレットを持つため、デスクトップ ヒープを若干 (一般的には数 KB) 消費します。
そのため、非対話型のセッションで多数のバッチ処理を並行して実行すると、小さな消費の積み重ねでデスクトップ ヒープを消費しきってしまい、結果としてデスクトップ ヒープが枯渇した状態になります。

 https://blogs.technet.microsoft.com/askcorejp/2018/01/19/%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97-%E3%83%92%E3%83%BC%E3%83%97%E3%81%AE%E6%9E%AF%E6%B8%87/

 

どうやら、非対話の処理(バックグラウンドの処理)であってもデスクトップヒープを消費するので、大量に実行するとデスクトップヒープが枯渇するようだ。

意図した順でログが出ているか確認するスクリプト

ログファイルの解析にて、意図した順でログが出ているかを確認することが必要な場面があったので、それを確認する perlスクリプト checkOrder.pl を作成した。

使い方は、スクリプト冒頭の以下の箇所を順番を確認したいもの(正規表現)に書き換えてから、

my @logs = ("test log message1", "test log message2", "test log message3");

perl checkOrder.pl 解析対象のログファイル

として実行する。
上記は、ログファイル内にて、test log message1 -> test log message2 -> test log message3 という行が順番で出力されているかどうか確認する例である。
なお、チェック対象以外のログについては気にしない。順番チェック対象のログ(行)が順番で出てきているのかどうか(だけ)を確認するものである。


全て順番通りであれば、

The order is OK.

と出力され、一か所でも順番通りでないところがあれば、例えば以下のように、順番が意図通りでない箇所を出力して終了する。

test log message2 (at 15 lines) is not in the order...


checkOrder.pl

use strict;
use warnings;

#------------------------------------------
# User customize. Specify messages by correct order (as regex).
# The example below means this script checks if log messages appears in the following order.
#  (1) "test log message1"
#  (2) "test log message2"
#  (3) "test log message3"
#------------------------------------------
my @logs = ("test log message1", "test log message2", "test log message3");

# Check the args.
my $inFile = $ARGV[0];
if (! -f $inFile) {
    die "There is not $inFile file...";
}

open(my $inFh,  "< $inFile")  or die("Error :$!");

my $currentLogNum = -1;
my $prevLogNum = -1;
my $found = 0;
my $lineNum = 0;
foreach my $line (<$inFh>) {
    $lineNum++;
    my $logNum = 0;
    foreach my $log (@logs) {
        # Check if the line has one of the logs.
        if ($line =~ /$log/) { # $line has $log (as a regex).
            $found = 1;
            $prevLogNum = $currentLogNum;
            $currentLogNum = $logNum;

            # Check if the order is correct.
            if ($currentLogNum != -1 and $prevLogNum != -1) {
                unless (isCorrectOrder($prevLogNum, $currentLogNum)) {
                    print("$line (at $lineNum lines) is not in the order...");
                    exit;
                }
            }
            last;
        }
        $logNum++;
    }
}

close($inFh);

if ($found) {
    print("The order is OK.");
}
else {
    print("There are not target logs...");
}

sub isCorrectOrder {
    my ($prevLogNum, $currentLogNum) = @_;
    if (($currentLogNum == $prevLogNum + 1) or ($prevLogNum == $#logs and $currentLogNum == 0)) {
        return 1;
    }
    return 0;
}


マルチスレッドのプログラムにて、各スレッドが意図した順で動いているのかを確認する際、各スレッドのログが意図した順で出ているのかでチェックすると有効なことがあり、このスクリプトを作成した。ログファイルが短ければ目視で確認できるが、長大な場合は目視で確認できないので、そういう時に使えると思う。

jarファイルの署名の削除

テストのため一時的に Java の jarファイルの署名を削除したいことがある。その時の手順について簡単に纏める。

  1. jarファイルを開く。(7zipやWinZipを使用)
  2. jarファイルの META-INF ディレクトリ内の署名関係のファイル(*.SF, *.RSA) を削除する。
  3. META-INF ディレクトリ内の MANIFEST.MF ファイルから署名関係の箇所を削除する。
  4. jarファイルを閉じ、保存する。

 

参考

https://kbdeveloper.qoppa.com/removing-a-signature-from-a-signed-jar-file/

https://stackoverflow.com/questions/7757083/how-do-i-unsign-a-jar?noredirect=1&lq=1