JavaRush /Java Blog /Random-JA /コーヒーブレイク#88。メタデータの力: スパゲッティ コードの扱い方。Java のガベージ コレクション - そ...

コーヒーブレイク#88。メタデータの力: スパゲッティ コードの扱い方。Java のガベージ コレクション - その仕組みとその利点

Random-JA グループに公開済み

メタデータの力: スパゲッティ コードの扱い方

出典: Hackernoon 私たちは皆、共通のアプローチと既知のパターンを使用して、最小限の労力で最大限の効果をもたらすアプリケーションを作成しようとします。当社には、日常的な操作を実行してくれる優れたライブラリと強力なフレームワークがあります。これらすべてを使用して、ビジネス ロジックのみに焦点を当てます。ただし、この追求により、特に既製のソリューションがない関数を実装する場合には、スパゲッティ コードに行き着くことがよくあります。この記事では、私の経験では、すべての開発者が評価しているわけではない強力なツールを 1 つ紹介したいと思います。このツールはほとんどのプログラミング言語に存在し、多くのフレームワーク (アノテーション) でよく使用されます。 コーヒーブレイク#88。 メタデータの力: スパゲッティ コードの扱い方。 Java のガベージ コレクション - その仕組みとその利点 - 1

スパゲッティは好きですか?

数年前に私が遭遇した例を見てみましょう。Excel スプレッドシートを解析して、解析されたデータをデータベースに入れる必要がありました。また、データベースからデータの一部を収集してスプレッドシートを作成したいと考えていました。実装には、有名な Java ライブラリである Apache POI を使用しました。ライブラリの API を使用すると、シート、行、セル、その他の要素を手動で作成できるため、作業が容易になります。これは非常に良いことですが、さまざまな Excel スプレッドシートを生成する必要がある場合、コードは完全に読み取れなくなり、サポートできなくなります。その結果、よくあることですが、アプリケーションの最初のバージョンは単にひどいものであることが判明しました。この実装は、解析に必要なすべてのフィールドを含む文字列を表すデータ クラスで構成されていました。Excel フィールドをセルごとに解析し、新しく作成されたデータ クラス インスタンスに配置するパーサーもありました。最初、プログラムはうまく機能し、必要なことを実行しました。問題は、いくつかの変更を加える段階になったときに始まりました。コードが読み取れませんでした。このコードを書いた私でさえ、必要な新しい関数を実装するために新しい行を配置する適切な場所を見つけることができませんでした。

注釈でのレスキュー

この注釈スパゲッティ コードからアプリケーションを保存しました。サポートされていないコードを削除するには、解析する列、セルに含まれるデータの種類、その他すべてを決定するロジックを別の場所に移動する必要がありました。これを行うために、各クラス フィールドの列名を指定するアノテーションを作成しました。注釈には、セルの色とフォントを選択できる変数も追加しました。したがって、解析クラスのコードは大幅に削減されました。1 つのプロセッサのみが、注釈から取得したパラメータに基づいてスプレッドシートを動的に作成しました。勝利でした。次に、アプリケーションに変更を加えるには、アノテーションを含むクラスを作成するだけで済みました。このソリューションは、アノテーションを使用して JSON を解析する Jackson ライブラリを彷彿とさせるもので、Jackson または同様のライブラリがいかに便利であるかを説明する必要はないと思います。
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ColumnExcel {

    String name() default "";

    int position();

    ExcelColumnDataFormat cellTypePattern() default ExcelColumnDataFormat.NONE;

    IndexedColors cellColor() default IndexedColors.AUTOMATIC;

    ExcelTotalFormula total() default ExcelTotalFormula.NONE;

}
ColumnExcel columnExcel = field.getAnnotation(ColumnExcel.class);
アプリケーションが進化するにつれて、スプレッドシート内に関数を含むセルを作成するために使用できる新しい注釈が追加されました。さまざまなフィールドの乗算や減算が可能で、一般的な Excel 関数も使用できます。列ごとの合計を表示するために合計行も追加しました。そして、メインのパーサーを少し変更し、クラスにアノテーションを追加するだけで、これらすべてを実行しました。
@ColumnExcel(
            name = "Views",
            position = 4,
            total = ExcelTotalFormula.SUM)
    private BigDecimal variableC;

    @ColumnExcelFormula(
            name = "Conversion",
            position = 5,
            cellTypePattern = CellDataTypeFormatPattern.PERCENTAGE
    )
    public String variableD(int rowNumber) {
        return new CellAddress(rowNumber, 4).formatAsString() + "*"
		+ new CellAddress(rowNumber, 2).formatAsString();
    }

    @ColumnExcelTotalFormula(position = 4, cellTypePattern = CellDataTypeFormatPattern.RUR)
    public static String getVariableCTotalFormula(int firstRowNum, int lastRowNum) {
        return "SUM( " + new CellAddress(firstRowNum, 4).formatAsString() + ":"
		+ new CellAddress(lastRowNum, 4).formatAsString() + ")";
    }

Java のガベージ コレクション - その仕組みとその利点

出典: Dev.to ガベージ コレクションとは、メモリ内の未使用のオブジェクトを破棄またはクリーンアップすることを意味します。Java は、オブジェクトが作成されるとヒープ上の一部のメモリを使用するため、メモリの割り当て解除を自動的に処理します。 コーヒーブレイク#88。 メタデータの力: スパゲッティ コードの扱い方。 Java のガベージ コレクション - その仕組みと利点 - 2

使い方?

Java が登場する前、最も人気のあるプログラミング言語は C または C++ でした。これらの言語を話せるなら、言語が自分の記憶を手動で管理していることを知っているはずです。たとえば、C には、バッファ メモリを使用できるcalloc()malloc()realloc()などのメソッドがあります。プログラムに必要なメモリ量を決定し、この API によって呼び出される内容を指定する必要があります。その後、メモリ バッファを取得して、リンク リスト ノードなどを作成できます。プログラムが終了すると、ある時点でそのメモリをクリーンアップする必要があります。そのため、C で書かれた大規模なアプリケーションはバッファ メモリを割り当て続け、フラッシュするのを忘れることがあります。これにより、最終的にメモリ リークが発生し、アプリケーションに多くの問題が発生します。C や C++ とは異なり、Java 言語には、ガベージ コレクターと呼ばれるスレッドによる自動メモリ管理が備わっています。その主な目的は、アクセスできないオブジェクトを破棄してヒープ メモリを解放することです。ガベージ コレクターは常にバックグラウンドで実行されます。

Java でアクセスできないオブジェクトとは何ですか?

オブジェクトがガベージ コレクションを開始できるのはいつですか? アクセスできないオブジェクト、つまりアクティブなリンクがないオブジェクトがある場合。例を見てみましょう:
public static void main(String[] args)
{
// StringBuffer object sb is not eligible for garbage collection
StringBuffer sb = new StringBuffer("Flower Brackets");
System.out.println(sb);
// StringBuffer object sb is eligible for garbage collection
sb = null;
}
main メソッドでは、StringBufferオブジェクトとそれへの参照を作成しました。この時点では、StringBufferオブジェクトはガベージ コレクションの対象にはなりません。次に、 StringBufferオブジェクトを「null」に設定します。このオブジェクトはガベージ コレクションの対象となり、ヒープ メモリ内でアクセスできないオブジェクトになります。つまり、ガベージ コレクションは通常、オブジェクトがアクセスできなくなった場合に機能します。これは、オブジェクトが通常「if ブロック」またはメソッドのコンテキストで作成されることを意味します。したがって、メソッドの実行が完了するとオブジェクトはスコープ外になり、ガベージ コレクターによって破棄できるようになります。古いオブジェクトから新しいオブジェクトへの参照は限られた数で存在するため、アプリケーションに長期間存在するオブジェクトは通常、新しく作成されたオブジェクトではないことを意味します。ここでは、知っておくべき用語をいくつか紹介します。そのうちの 1 つは生きたオブジェクトです。これは、同じアプリケーション内の別のオブジェクトによって参照されるアプリケーション内のオブジェクトです。「死んだ」オブジェクトもあります。デッド オブジェクトとは、メソッド呼び出し中に作成されるアクセスできないオブジェクトであり、メソッド呼び出しが完了すると、オブジェクトはコンテキストから外れ、ヒープ上に留まります。

オブジェクトがガベージ コレクションの対象となるのはどのような場合ですか?

オブジェクトに参照変数がない場合、そのオブジェクトはガベージ コレクションの対象になります。

オブジェクトをガベージ コレクションに使用できるようにするにはどうすればよいですか?

以下にいくつかの方法を示します。
  1. null reference variable
    Student obj = new Student();
    obj = null;

  2. re-assign reference variable
    Student obj1 = new Student();
    Student obj2 = new Student();
    obj1 = obj2;

  3. reate anonymous object
    new Student();

    オブジェクトがガベージ コレクターで利用可能になった後、そのオブジェクトはすぐには破棄されません。

Java 仮想マシンがガベージ コレクターを実行すると、オブジェクトのみが破棄されます。 注:ガベージ コレクターは、「new」キーワードを使用して作成されたオブジェクトのみを収集します。「new」キーワードのないオブジェクトの場合は、finalize()メソッドを使用します。Java 仮想マシンでガベージ コレクターを実行するには、いくつかの方法があります。
  1. System.gc()メソッド

  2. Finalize()メソッド

  3. Runtime.getRuntime().gc()メソッド

静的gc()メソッドはSystemクラスにあります。このメソッドは、JVM にガベージ コレクターを呼び出すように要求します。Java アプリケーションがgc()メソッドを使用してガベージ コレクターを呼び出す 方法を見てみましょう。
public class GarbageCollector
{
public static void main(String[] args)
{
Employee obj1 = new Employee();
Employee obj2 = new Employee();
obj1 = null;
obj2 = null;
System.gc();
}
public void finalize()
{
System.out.println("object garbage collected");
}
}
結果:
オブジェクト ガベージ コレクション オブジェクト ガベージ コレクション
Finalize() メソッドは、オブジェクトがクリーンアップされる直前に呼び出されます。このメソッドはObjectクラスで定義されます。
protected void finalize() throws Throwable
  1. Finalizeメソッドは、データベースへの接続を閉じるために使用されます。

  2. このメソッドは、JVM ではなくガベージ コレクターによって呼び出されます。

  3. Finalize()メソッドをオーバーライドする必要があります。空の実装があるためです。

  4. これはオブジェクトごとに 1 回だけ呼び出されます。

getRuntime().gc()メソッドはランタイム クラスに存在します。現在の Java アプリケーションに関連付けられたRuntimeオブジェクトを返します。このメソッドを Java プログラムで見てみましょう。
public class Demo
{
public static void main(String[] args)
{
Demo obj1 = new Demo();
Demo obj2 = new Demo();
// nullifying reference variable
obj1 = null;
// nullifying reference variable
obj2 = null;
// running Garbage Collector
Runtime.getRuntime().gc();
}
@Override
protected void finalize() throws Throwable
{
System.out.println("Garbage collector called");
System.out.println("Object garbage collector: " + this);
}
}
結果:
オブジェクト ガベージ コレクターと呼ばれるガベージ コレクター: Demo@2130772 オブジェクト ガベージ コレクターと呼ばれるガベージ コレクター: Demo@cd4e940

ガベージ コレクションの利点:

  1. Java のガベージ コレクションは自動的に行われるため、使用済みメモリを解放するという追加の負担が軽減されます。これにより、Java プログラムのメモリがより効率的になります。
  2. ガベージ コレクションにより、プログラムの整合性が保証されます。
  3. ガベージ コレクターは JVM の一部であるため、追加のコードを記述する必要はありません。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION