ホームページ Java &#&チュートリアル Java での参照の使用法について

Java での参照の使用法について

Mar 16, 2017 am 10:19 AM

この記事は主に Java での Reference の使い方の詳細な説明に関する関連情報を紹介します。必要な方は参考にしてください

Java Reference 詳細

jdk 1.2 以降では、強い リファレンス 、ソフト リファレンス 、弱いリファレンス 。これら 4 つの概念への仮想参照である参照が導入されています。これら 4 つの概念についてはインターネット上に多くの説明がありますが、今日はコードに基づいて分析したものがほとんどです (参照型は Java パッケージ内にあります)。 lang.ref 内)。

1. 強参照(StrongReference)

強参照はGCによってリサイクルされず、java.lang.refには実際に対応する型がありません。例:


 Object obj = new Object();
ログイン後にコピー

ここでの obj 参照は強参照であり、GC によってリサイクルされません。

2. ソフト参照 (SoftReference)

ソフト参照は、JVM がメモリ不足を報告すると GC によってリサイクルされ、そうでない場合はリサイクルされません。プールすること。ソフト参照の使用法:


Object obj = new Object();
SoftReference<Object> softRef = new SoftReference(obj);
// 使用 softRef.get() 获取软引用所引用的对象
Object objg = softRef.get();
ログイン後にコピー

3. 弱参照(WeakReference)

GCは弱参照オブジェクトを発見すると、WeakReferenceで参照されているオブジェクトを解放します。弱い参照の使用法はソフト参照の使用法と似ていますが、リサイクル戦略が異なります。

4. Phantom Reference (PhantomReference)

GCは仮想参照オブジェクトを発見すると、PhantomReferenceオブジェクトをReferenceQueueキューに挿入します。このとき、PhantomReferenceが指すオブジェクトはGCによってリサイクルされません。ただし、ReferenceQueue が実際に処理されるまでリサイクルされません。仮想参照の使い方:


Object obj = new Object();
ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
PhantomReference<Object> phanRef = new PhantomReference<Object>(obj, refQueue);
// 调用phanRef.get()不管在什么情况下会一直返回null
Object objg = phanRef.get();
// 如果obj被置为null,当GC发现了虚引用,GC会将phanRef插入进我们之前创建时传入的refQueue队列
// 注意,此时phanRef所引用的obj对象,并没有被GC回收,在我们显式地调用refQueue.poll返回phanRef之后
// 当GC第二次发现虚引用,而此时JVM将phanRef插入到refQueue会插入失败,此时GC才会对obj进行回收
Reference<? extends Object> phanRefP = refQueue.poll();
ログイン後にコピー

簡単な定義を読んだ後、強参照は言うまでもなく、ソフト参照の説明も非常に明確です。 「仮想参照」引用」。

弱参照:


public static void main(String[] args) throws InterruptedException {
  Object obj = new Object();
  ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
  WeakReference<Object> weakRef = new WeakReference<Object>(obj, refQueue);
  System.out.println(weakRef.get());
  System.out.println(refQueue.poll());
  obj = null;
  System.gc();
  System.out.println(weakRef.get());
  System.out.println(refQueue.poll());
}
ログイン後にコピー

System.gc() は JVM に GC を実行するのに良い時期であることを伝えますが、具体的に実行するかどうかは JVM によって決定されるため、JVM がGC を実行し、結果が得られます。 つまり、(実際、このコードは通常 GC を実行します):


  java.lang.Object@de6ced
  null
  null
  java.lang.ref.WeakReference@1fb8ee3
ログイン後にコピー

実行結果から、GC は、weakRef.get() を呼び出すことで obj オブジェクトを取得することがわかります。実行されず、refQueue.poll() 返された null は、obj = null に設定した場合、ヒープ内に obj オブジェクトへの参照がありません。ここで、JVM は、weakRef.get( を通じて GC を実行しました。 ) null が返され、refQueue.poll() が WeakReference オブジェクトを返したので、JVM は obj をリサイクルした後、refQueue キューにweakRef を挿入します。

ダミー参照:


public static void main(String[] args) throws InterruptedException {
  Object obj = new Object();
  ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
  PhantomReference<Object> phanRef = new PhantomReference<Object>(obj, refQueue);
  System.out.println(phanRef.get());
  System.out.println(refQueue.poll());
  obj = null;
  System.gc();
  System.out.println(phanRef.get());
  System.out.println(refQueue.poll());
}
ログイン後にコピー

同様に、JVM が GC を実行すると、結果は次のようになります:


  null
  null
  null
  java.lang.ref.PhantomReference@1fb8ee3
ログイン後にコピー

実行結果から、前に述べたことが正しいことがわかります。 phanRef.get( ) は、状況に関係なく、JVM が GC を実行して仮想参照を検出すると、refQueue.poll() を呼び出すときに、対応する仮想参照キューに PhantomReference オブジェクトを挿入します。 PhantomReference オブジェクトを使用する場合、poll メソッドはまず PhantomReference の保持キュー キュー (ReferenceQueuesuperT>) を NULL に設定します。NULL オブジェクトは ReferenceQueue からを継承し、enqueue(Reference paramReference) メソッドをに上書きします。 return false し、obj が GC によって再度検出されると、JVM は PhantomReference を NULL キューに挿入しますが、挿入は失敗して false を返します。このとき、GC は obj をリサイクルします。実際、このコードでは、obj がリサイクルされているかどうかを知ることはできませんが、PhantomReference の javadocコメント には次のような文があります。可能であれば、対応するキューにエンキューされていますが、その参照先は

クリア

されていません。つまり、ファントム参照の参照キューは、何らかのアプリケーション コードによって明示的に処理される必要があります。シンプルなので、多くの人が理解できるはずだと思います): 「obj」が仮想的に到達可能であると GC が判断すると、そのオブジェクト (PhantomReference を参照) は対応するキューにエンキューされますが、そのポインターの世代はクリアされていません。つまり、仮想参照の参照キューは、アプリケーション コードによって明示的に処理される必要があります。

弱参照と仮想参照の使用

  软引用很明显可以用来制作caching和pooling,而弱引用与虚引用呢?其实用处也很大,首先我们来看看弱引用,举个例子:


class Registry {
  private Set registeredObjects = new HashSet();
 
  public void register(Object object) {
    registeredObjects.add( object );
  }
}
ログイン後にコピー

所有我添加进 registeredObjects 中的object永远不会被GC回收,因为这里有个强引用保存在registeredObjects里,另一方面如果我把代码改为如下:


class Registry {
   private Set registeredObjects = new HashSet();
 
   public void register(Object object) {
     registeredObjects.add( new WeakReference(object) );
   }
 }
ログイン後にコピー

  现在如果GC想要回收registeredObjects中的object,便能够实现了,同样在使用HashMap如果想实现如上的效果,一种更好的实现是使用WeakHashMap。

而虚引用呢?我们先来看看javadoc的部分说明:

Phantom references are useful for implementing cleanup operations that are necessary before an object gets garbage-collected. They are sometimes more flexible than the finalize() method.

翻译一下:

虚引用在实现一个对象被回收之前必须做清理操作是很有用的。有时候,他们比finalize()方法更灵活。

很明显的,虚引用可以用来做对象被回收之前的清理工作。

以上がJava での参照の使用法についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

カプセルの量を見つけるためのJavaプログラム カプセルの量を見つけるためのJavaプログラム Feb 07, 2025 am 11:37 AM

カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4

PHP対Python:違いを理解します PHP対Python:違いを理解します Apr 11, 2025 am 12:15 AM

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHPは、シンプルな構文と高い実行効率を備えたWeb開発に適しています。 2。Pythonは、簡潔な構文とリッチライブラリを備えたデータサイエンスと機械学習に適しています。

See all articles