危険なクラスとは何ですか?
Javaはもともと、安全な制御された環境として設計されていました。それにもかかわらず、Java Hotspotには、メモリやスレッドを直接操作できる低レベルの操作を提供する「バックドア」が含まれています。このバックドアクラス-sun.misc.unsafe-は、java.nioやjava.util.concurrentなど、JDKが独自のパッケージで広く使用されています。ただし、このバックドアは、生産環境ではまったく推奨されません。このAPIは非常に安全でなく、軽くなく、不安定であるためです。この不安定なクラスは、ホットスポットJVMの内部構造のビューを提供し、変更できます。 C ++デバッグなしで仮想マシンの内部構造を学習するために使用できる場合もあれば、パフォーマンス監視および開発ツールとして使用できる場合もあります。
導入
最近、私はJava Concurrentパッケージのソースコードを見ていて、魔法の安全でないクラスを発見しました。私はそれを注意深く勉強し、ここであなたと共有しました。
安全でないクラスはsun.miscパッケージの下にあり、Java標準に属していません。ただし、いくつかの広く使用されている高性能開発ライブラリを含む多くの基本的なJavaクラスライブラリは、Netty、Cassandra、Hadoop、Kafkaなどの安全でないクラスに基づいて開発されています。危険なクラスは、Javaの運用効率を改善し、Java言語の基礎となる操作能力を高めるのに大きな役割を果たします。
安全でないクラスは、JavaにC言語のポインターのようなメモリスペースを動作させる能力を与え、ポインターの問題ももたらします。安全でないクラスを過度に使用すると、エラーの可能性が高まるため、Javaは使用することを推奨せず、公式の文書はほとんどありません。 OracleはJava 9から安全でないクラスを削除することを計画しています。もしそうなら、それは大きすぎるでしょう。
通常、明確な目的があり、それを深く理解していない限り、安全でないクラスを使用しないことが最善です。危険なクラスを使用するには、いくつかのトリッキーな方法を使用する必要があります。安全でないクラスはシングルトンパターンを使用しているため、静的な方法getunsafe()を使用して取得する必要があります。ただし、安全でないクラスはそれを制限しています。通常の呼び出しの場合、SecurityExceptionの例外がスローされます。メインクラスローダーによってロードされたクラスのみがこのメソッドを呼び出すことができます。ソースコードは次のとおりです。
public static unsafe getunsafe(){class var0 = reflection.getCallerClass(); if(!vm.IssystemDomainLoader(var0.getClassLoader())){throw new SecurityException( "Unsafe"); } else {return theunsafe; }}BootClassPathパラメーターの設定など、メインクラスローダーを使用してユーザーコードをロードする方法もあります。しかし、より簡単な方法は、次のようにJava反射を使用することです。
フィールドf = unsafe.class.getDeclaredfield( "theunsafe"); f.setAccessible(true);安全でないUnsafe =(安全でない)F.get(null);
安全でないインスタンスを取得した後、私たちはやりたいことを何でもすることができます。安全でないクラスは、次の機能を提供します。
1。メモリ管理。メモリの割り当て、メモリの解放などを含む。
この部分には、AllocateMemory(Allocatememory)、Reallocatememory(Reallocatememory)、Copymemomory(コピーメモリ)、フリーメモリ(フリーメモリ)、GetAddress(GetGet Memoryアドレス)、アドレスサイズ、Pagesize、GetInt(Integer Pointed by Memory dorders)、GetIntolovatile(veteger of suptess of supted supted suptess asted suptess)が含まれます。 Putint(指定されたメモリアドレスに整数を書き込みます)、Putintvolatile(指定されたメモリアドレスに整数を書き込み、揮発性セマンティクスをサポート)、PutOrdereDINT(指定されたメモリアドレスに整数を書き込み、順序付けまたは遅延されたメソッドに書き込みます)。 getXxxとputxxxには、さまざまな基本タイプの操作が含まれています。
Copymemoryメソッドを使用して、各オブジェクトのクローンメソッドを実装せずに一般的なオブジェクトコピーメソッドを実装できます。もちろん、この一般的な方法は、オブジェクトの浅いコピーのみを実現できます。
2。型破りなオブジェクトのインスタンス化。
AllocateInstance()メソッドは、インスタンスを作成する別の方法を提供します。通常、新しいまたは反射でオブジェクトをインスタンス化できます。 AllocateInstance()メソッドを使用して、コンストラクターやその他の初期化方法を呼び出すことなく、オブジェクトインスタンスを直接生成します。
これは、オブジェクトを脱出する場合に役立ち、コンストラクターを呼び出すことなく再構築および最終フィールドの設定を可能にします。
3。操作クラス、オブジェクト、および変数。
このパートには、staticFieldOffset(静的ドメインオフセット)、defineClass(定義クラス)、definnonymousclass(定義匿名クラス)、ensureclassInitialized(Class Intilemination)、ObjectFieldOffset(オブジェクトドメインオフセット)およびその他のメソッドが含まれます。
これらの方法により、オブジェクトのポインターを取得できます。ポインターを相殺することにより、ポインターによって指摘されたデータを直接変更するだけでなく(プライベートであっても)、JVMがすでにゴミを検討してリサイクルできるオブジェクトを見つけることさえできます。
4。アレイ操作。
このパートには、ArrayBaseOffset(配列の最初の要素のオフセットアドレスを取得)、ArrayIndexscale(配列内の要素の増分アドレスを取得)などが含まれます。ArrayBaseOffsetは、ArrayIndexscaleと組み合わせて使用され、メモリの配列の各要素の位置を見つけることができます。
Javaの最大配列値はinteger.max_valueであるため、安全でないクラスのメモリ割り当て方法を使用して超大型アレイを実装できます。実際、そのようなデータはCアレイと見なすことができるため、適切なタイミングでメモリを解放することに注意を払う必要があります。
5。マルチスレッド同期。ロックメカニズム、CAS操作などを含む。
このパートには、MonitorEnter、TryMonitorEnter、Monitorexit、CompareAndSwapint、CompareAndSwap、およびその他の方法が含まれます。
その中で、Monitorenter、TryMonitorenter、およびMonitorexitは廃止されているとマークされており、推奨されていません。
安全でないクラスのCAS操作が最も使用される場合があり、Javaのロックメカニズムに新しいソリューションを提供します。たとえば、AtomicIntegerおよびその他のクラスはすべてこの方法を通じて実装されます。 CompareAndSwapメソッドはアトミックであり、重いロックメカニズムを回避し、コード効率を向上させることができます。これは楽観的なロックであり、通常、ほとんどの場合、人種の状態がなく、操作が失敗した場合、成功するまで再試行し続けると考えられています。
6。中断して復元します。
この部品には、公園、幼稚園、その他の方法が含まれます。
パークメソッドを介してスレッドを一時停止します。パークに電話をかけた後、スレッドはタイムアウトまたは割り込みが発生するまでブロックされます。 Uparkは、保留中のスレッドを終了して通常に復元できます。 Concurrencyフレームワーク全体のスレッド上のサスペンド操作は、Locksupportクラスにカプセル化されています。 Locksupportクラスにはパックメソッドにはさまざまなバージョンがありますが、最終的にはUnsafe.Park()メソッドが呼び出されます。
7。メモリバリア。
この部分には、荷重フェンス、ストアフェンス、フルフェンス、その他の方法が含まれます。これは、Java 8で新たに導入され、コードの並べ替えを避けるためのメモリの障壁を定義します。
loadfence()とは、メソッド前のすべての負荷操作がメモリバリアの前に完了することを意味します。同様に、StoreFence()とは、このメソッドの前のすべてのストア操作がメモリバリアの前に完了することを意味します。 Fullfence()とは、メソッドの前にメソッドが完了する前のすべての負荷および保存操作を意味します。
要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。