FAO(国際連合食糧農業機関)の報告書によると、世界では食料生産量の3分の1に当たる約13億トンの食料が毎年廃棄されています。
日本でも1年間に約612万トン(2017年度推計値)もの食料が捨てられており、これは東京ドーム5杯分とほぼ同じ量。日本人1人当たり、お茶碗1杯分のごはんの量が毎日捨てられている計算になります。
⇧ ちょっと旧い情報だけども、日本の「食品ロス」の量が想像以上に多いことに驚きを隠せない、どうもボクです。
というわけで、今回もJavaの話です。
レッツトライ~。
JavaのGC(Garbage Collector)は改良がされてるらしい
Javaもバージョンによっては、破壊的な変更が起こってるらしいですね。
ちなみに、
本記事では、アプリケーションでのGCによる一時停止時間についての悩みを解消できるいくつかの方法を紹介しました。G1の改善は続くものの、ヒープ・サイズが増加し、一時停止時間が許容されにくくなるにつれて、ShenandoahやZGCなどの新しいGCによって、スケーラブルで一時停止時間の短い未来が実現することを覚えておいて損はありません。
https://blogs.oracle.com/otnjp/understanding-the-jdks-new-superfast-garbage-collectors-ja
⇧ってな感じで、将来的に「GC(Garbage Collector)」が刷新されることもあるんですかね?
他にも、
⇧ 注意事項は上記サイト様が詳しいです。
JavaのGC(Garbage Collector)って何?
そもそも、Javaの「GC(Garbage Collector)」って何?
Oracleさんの説明によると、
Java is a programming language and computing platform first released by Sun Microsystems in 1995.
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
⇧ Javaってのが1995年にリリースされたわけなんですが、どうも「JVM(Java Virtual Machine)」の一機能ってことになるみたいですと。
Javaの構成については、
⇧ 上記サイト様が詳しいです。
Java Development Kit (JDK) is the software for programmers who want to write Java programs.
The JDK consists of a set of separate programs for compiling, running, and testing Java programs. So as you can see on the diagram down, JDK contains JRE and Development Tools (e.g. javac, java, etc.)
JDK = JRE + Development Tools
https://www.dev-guide.org/the-java-language-specification-api-ide-jdk-jre-and-jvm/
Java Runtime Environment (JRE) is the software for consumers who want to run Java programs. It contains the API (Java libraries), Java Virtual Machine (JVM) and other files.
JRE = API + JVM + other files
https://www.dev-guide.org/the-java-language-specification-api-ide-jdk-jre-and-jvm/
で、「JVM(Java Virtual Machine)」がどんな構成かと言うと、
⇧ ってな感じですと。「HotSpot」以外の「JVM(Java Virtual Machine)」はちょっと分からんけども。
で、「GC(Garbage Collector)」ってのは、
There are three components of the JVM that are focused on when tuning performance. The heap is where your object data is stored. This area is then managed by the garbage collector selected at startup. Most tuning options relate to sizing the heap and choosing the most appropriate garbage collector for your situation. The JIT compiler a
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
⇧ Javaアプリケーションのパフォーマンスに関わってくる「JVM(Java Virtual Machine)」の3つのコンポーネントの内の1つということらしい。
「GC(Garbage Collector)」の超ザックリとした概要は、
⇧ 上図のような「Heap」っていうメモリ領域に配置されるオブジェクトを管理するってことかと。
オブジェクトは、
HotSpotの専門用語である"OOP"("Ordinary Object Pointer")は、オブジェクトに対する管理ポインタを表します。
https://www.oracle.com/technetwork/jp/articles/java/compressedoops-427542-ja.html
⇧ OOP(Ordinary Object Pointer)って仕組みで「JVM(Java Virtual Machine)」が管理してるってことだとは思うんだけど、「GC(Garbage Collectors)」との関係がいまいちよく分からんかったです。
GC(Garbage Collection)のログのオプションでハマる
JVM(Java Virtual Machine)にGC(Garbage Collectors)って機能があることが分かったんだけど、
って、GCのって略称だけだと、どっちのこと言ってるのか分からんくなるよね...
文章にするときは、略称だけじゃなく正式名称も記載するようにしたいですね。
で、「GC(Garbage Collector)」によって「GC(Garbage Collection)」が行われる際にログが取れるらしいんですが、
Convert GC Logging Flags to Xlog
Table 2-1 Mapping Legacy Garbage Collection Logging Flags to the Xlog Configuration
⇧ Java 9 から結構変更があるらしい。
なので、もし、GC(Garbage Collection)のログに関するオプションとかを設定してJavaアプリケーションを実行してる場合で、Javaのバージョンアップをする場合は何かと注意が必要ですかね。
ちなみに、
⇧ 上記サイト様の「061:複合(1)」ってのを試して、GC(Garbage Collection)のログに関するオプションが変わってることに気づきました。
自分は、以下のようにEclipse でJavaプロジェクトを作成して実施しました。Java 11を使ってます。
Windowsのバッチだけ修正してます。
変更前
@ECHO OFF @REM ------------------------------------ @REM java-100practices @REM answer061.bat @REM author: ts0818 @REM ------------------------------------ @REM 変数設定 SET CLASSPATH="C:\Eclipse-2020-06\pleiades-2020-06-java-win-64bit-jre_20200702\pleiades\workspace\java_one_hundred_nock\bin" SET SOURCEPATH="C:\Eclipse-2020-06\pleiades-2020-06-java-win-64bit-jre_20200702\pleiades\workspace\java_one_hundred_nock\src" SET JAVAC="C:\Eclipse-2020-06\pleiades-2020-06-java-win-64bit-jre_20200702\pleiades\java\11\bin\javac.exe" SET JAVAE="C:\Eclipse-2020-06\pleiades-2020-06-java-win-64bit-jre_20200702\pleiades\java\11\bin\java.exe" SET TARGET=Answer061 SET JAVA=.java SET PACKAGE=java_one_hundred_nock.sixtyone. SET LOG=log.txt @REM 変数連結 SET TARGET_JAVA_STR=%TARGET%%JAVA% SET TARGET_JAVA="%TARGET_JAVA_STR%" SET TARGET_CLASS_STR=%PACKAGE%%TARGET% SET TARGET_CLASS="%TARGET_CLASS_STR%" @REM Javaのコンパイル %JAVAC% -sourcepath %SOURCEPATH% -d %CLASSPATH% -encoding UTF-8 %TARGET_JAVA% >> %LOG% 2>&1 IF ERRORLEVEL 1 GOTO FAILURE @REM Javaの実行 %JAVAE% -cp %CLASSPATH% -Xms8m -Xmx8m -XX:NewSize=1536k -XX:MaxNewSize=1536k -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails %TARGET_CLASS% >> %LOG% 2>&1 IF ERRORLEVEL 1 GOTO FAILURE GOTO SUCCESS :FAILURE EXIT /B %ERRORLEVEL% :SUCCESS
⇧ 実行すると、エラーが出るんですが、
the flag PrintGCTimeStamps has been removed together with others via bug https://bugs.openjdk.java.net/browse/JDK-8145092 in JDK9. It is the implementation of JEP 271: "Unified GC Logging" (https://openjdk.java.net/jeps/271). So for JDK11 you should read the JEP and adjust your gc logging settings accordingly.
⇧ ってことで、Java 9 でJava実行時に設定できるGC(Garbage Collection)のログのオプションが刷新されたってことみたいね。
今回は、Java 11を使ってるので、オプションを変更で。
■変更後
@ECHO OFF @REM ------------------------------------ @REM java-100practices @REM answer061.bat @REM author: ts0818 @REM ------------------------------------ @REM 変数設定 SET CLASSPATH="C:\Eclipse-2020-06\pleiades-2020-06-java-win-64bit-jre_20200702\pleiades\workspace\java_one_hundred_nock\bin" SET SOURCEPATH="C:\Eclipse-2020-06\pleiades-2020-06-java-win-64bit-jre_20200702\pleiades\workspace\java_one_hundred_nock\src" SET JAVAC="C:\Eclipse-2020-06\pleiades-2020-06-java-win-64bit-jre_20200702\pleiades\java\11\bin\javac.exe" SET JAVAE="C:\Eclipse-2020-06\pleiades-2020-06-java-win-64bit-jre_20200702\pleiades\java\11\bin\java.exe" SET TARGET=Answer061 SET JAVA=.java SET PACKAGE=java_one_hundred_nock.sixtyone. SET LOG=log.txt @REM 変数連結 SET TARGET_JAVA_STR=%TARGET%%JAVA% SET TARGET_JAVA="%TARGET_JAVA_STR%" SET TARGET_CLASS_STR=%PACKAGE%%TARGET% SET TARGET_CLASS="%TARGET_CLASS_STR%" @REM Javaのコンパイル %JAVAC% -sourcepath %SOURCEPATH% -d %CLASSPATH% -encoding UTF-8 %TARGET_JAVA% >> %LOG% 2>&1 IF ERRORLEVEL 1 GOTO FAILURE @REM Javaの実行 %JAVAE% -cp %CLASSPATH% -Xms8m -Xmx8m -XX:NewSize=1536k -XX:MaxNewSize=1536k -verbose:gc -Xlog:gc* %TARGET_CLASS% >> %LOG% 2>&1 IF ERRORLEVEL 1 GOTO FAILURE GOTO SUCCESS :FAILURE EXIT /B %ERRORLEVEL% :SUCCESS
⇧ ってな感じで、今回はJava 11を使っているので、Java実行時のGC(Garbage Collection)のログのオプションを修正する必要がありますかね。(Java 8とかであれば修正前ので動くかと)
で結果として、「java.lang.OutOfMemoryError」が起これば良いらしい。
Javaのバージョンアップ、フレームワークのバージョンアップ、ミドルウェアのバージョンアップ、考えなければいけないことが多くて疲れますね...
今回はこのへんで。