文字列を解析する単純なスキャナーを実行していますが、頻繁に呼び出すと OutOfMemory エラーが発生することがわかりました。このコードは、文字列の配列に対して繰り返し構築されるオブジェクトのコンストラクターの一部として呼び出されます。
編集:詳細情報のコンストラクターは次のとおりです。Scanner に関する try-catch 以外では、それほど多くは発生していません
public Header(String headerText) {
char[] charArr;
charArr = headerText.toCharArray();
// Check that all characters are printable characters
if (charArr.length > 0 && !commonMethods.isPrint(charArr)) {
throw new IllegalArgumentException(headerText);
}
// Check for header suffix
Scanner sc = new Scanner(headerText);
MatchResult res;
try {
sc.findInLine("(\\D*[a-zA-Z]+)(\\d*)(\\D*)");
res = sc.match();
} finally {
sc.close();
}
if (res.group(1) == null || res.group(1).isEmpty()) {
throw new IllegalArgumentException("Missing header keyword found"); // Empty header to store
} else {
mnemonic = res.group(1).toLowerCase(); // Store header
}
if (res.group(2) == null || res.group(2).isEmpty()) {
suffix = -1;
} else {
try {
suffix = Integer.parseInt(res.group(2)); // Store suffix if it exists
} catch (NumberFormatException e) {
throw new NumberFormatException(headerText);
}
}
if (res.group(3) == null || res.group(3).isEmpty()) {
isQuery= false;
} else {
if (res.group(3).equals("?")) {
isQuery = true;
} else {
throw new IllegalArgumentException(headerText);
}
}
// If command was of the form *ABC, reject suffixes and prefixes
if (mnemonic.contains("*")
&& suffix != -1) {
throw new IllegalArgumentException(headerText);
}
}
プロファイラーのメモリ スナップショットは、Scanner.findInLine() の read(Char) メソッドが、数十万の文字列をスキャンする操作中に大量のメモリを割り当てられることを示しています。数秒後、すでに 38MB 以上が割り当てられています。
コンストラクターで使用した後にスキャナーで close() を呼び出すと、GC によってクリアされる古いオブジェクトにフラグが立てられると思いますが、どういうわけかそれは残り、読み取りメソッドはヒープを満たす前にギガバイトのデータを蓄積します。
誰かが私を正しい方向に向けることができますか?