Was ist die unsichere Klasse?
Java wurde ursprünglich als sichere kontrollierte Umgebung konzipiert. Trotzdem enthält Java Hotspot immer noch eine "Backdoor", die einige niedrige Operationen bietet, die direkt Speicher und Threads manipulieren können. Diese Backdoor -Klasse - sun.misc.unsafe - wird in seinen eigenen Paketen von JDK wie Java.nio und Java.util.Concurrent häufig verwendet. Diese Hintertür wird jedoch in Produktionsumgebungen überhaupt nicht empfohlen. Weil diese API sehr unsicher, nicht leicht und instabil ist. Diese unsichere Klasse bietet einen Blick auf die interne Struktur des Hotspot -JVM und kann geändert werden. Manchmal kann es verwendet werden, um die interne Struktur der virtuellen Maschine ohne C ++ -Debuggen zu lernen, und manchmal kann sie als Leistungsüberwachungs- und Entwicklungstools verwendet werden.
Einführung
Vor kurzem habe ich mir den Quellcode von Java -Paketen angesehen und die magische unsichere Klasse entdeckt. Ich habe es sorgfältig studiert und hier mit Ihnen geteilt.
Die unsichere Klasse befindet sich unter der Sonne.misc -Paket und gehört nicht zum Java -Standard. Viele grundlegende Bibliotheken der Java-Klasse, einschließlich einiger weit verbreiteter Hochleistungsbibliotheken, werden jedoch auf der Grundlage einer unsicheren Klasse entwickelt, wie Netty, Cassandra, Hadoop, Kafka usw. Die unsichere Klasse spielt eine große Rolle bei der Verbesserung der Effizienz der Java-Betrieb und der Verbesserung der zugrunde liegenden Betriebsfähigkeit der Java-Sprache.
Die unsichere Klasse gibt Java die Möglichkeit, Speicherplatz wie Zeiger in der C -Sprache zu bedienen, und bringt auch Zeigerprobleme. Die übermäßige Verwendung der unsicheren Klasse erhöht die Wahrscheinlichkeit von Fehlern, sodass Java nicht empfohlen wird, sie zu verwenden, und es gibt fast keine offizielle Dokumentation. Oracle plant, die unsichere Klasse aus Java 9 zu entfernen, und wenn dies der Fall ist, wäre es zu groß.
Normalerweise ist es am besten, die unsichere Klasse nicht zu verwenden, es sei denn, sie hat einen klaren Zweck und hat auch ein detailliertes Verständnis dafür. Um die unsichere Klasse zu verwenden, müssen Sie einige knifflige Methoden anwenden. Die unsichere Klasse verwendet ein Singleton -Muster und muss durch eine statische Methode Getunsafe () erhalten werden. Die unsichere Klasse hat sie jedoch eingeschränkt. Wenn es sich um einen normalen Anruf handelt, wird eine SecurityException -Ausnahme ausgelöst. Nur die vom Hauptklassenlader geladene Klasse kann diese Methode aufrufen. Der Quellcode lautet wie folgt:
public static unsicherer GetunSafe () {class var0 = reflection.getCallerClass (); if (! } else {return theunsafe; }}Es gibt auch einige Möglichkeiten, den Benutzercode mithilfe des Hauptklassenloaders zu laden, z. Der einfachere Weg ist jedoch, Java Reflection wie folgt zu verwenden:
Feld f = unsicher.class.getDeclaredfield ("theunsafe"); f.setAccessible (wahr); Unsicher unsicher = (unsicher) f.get (null);Nachdem wir die unsichere Instanz erhalten haben, können wir tun, was wir wollen. Die unsichere Klasse bietet die folgenden Funktionen:
1. Speicherverwaltung. Einschließlich der Zuweisung von Speicher, dem Befreiungsspeicher usw.
This part includes allocateMemory (allocateMemory), reallocateMemory (reallocateMemory), copyMemory (copy memory), freeMemory (free memory), getAddress (getget memory address), addressSize, pageSize, getInt (get the integer pointed to by the memory address), getIntVolatile (get the integer pointed to by the memory address and supports volatile Semantik), Putint (schreiben Sie die Ganzzahl an die angegebene Speicheradresse), Putintvolatile (schreiben Sie die Ganzzahl an die angegebene Speicheradresse und unterstützt die volatile Semantik), PutorderEdint (schreiben Sie die Ganzzahl an die angegebene Speicheradresse, geordnete oder verzögerte Methoden). GETXXX und PUTXXX enthalten verschiedene grundlegende Arten von Operationen.
Mit der Copymemory -Methode können wir eine allgemeine Objektkopie -Methode implementieren, ohne die Klonmethode für jedes Objekt zu implementieren. Natürlich kann diese allgemeine Methode nur das flache Kopieren des Objekts erreichen.
2. Unkonventionelle Objekt -Instanziierung.
Die AllocalInstance () -Methode bietet eine weitere Möglichkeit, eine Instanz zu erstellen. Normalerweise können wir Objekte mit neuer oder Reflexion instanziieren. Verwenden Sie die Methode alocalcinstance (), um Objektinstanzen direkt zu generieren, ohne Konstruktoren und andere Initialisierungsmethoden aufzurufen.
Dies ist nützlich, wenn sie Objekte deserialisieren und den Wiederaufbau und das Einstellen endgültiger Felder ermöglichen, ohne Konstruktoren aufzurufen.
3.. Betriebsklassen, Objekte und Variablen.
Dieser Teil umfasst staticFieldOffset (statischer Domänenversatz), Definition (Definitionsklasse), DefineanonyousClass (Definition Anonymous Class), sealeclassinitialisiert (sicherstellen der Klasseninitialisierung), ObjectFieldOffset (Objektdomänen -Offset) und andere Methoden.
Durch diese Methoden können wir den Zeiger des Objekts erhalten. Durch den Ausgleich des Zeigers können wir nicht nur die vom Zeiger vermittelten Daten (auch wenn sie privat sind) ändern, sondern auch Objekte finden, die der JVM bereits in Betracht gezogen hat und recycelt werden kann.
4. Array -Betrieb.
Dieser Teil enthält ArrayBaseOffset (erhält die Offset -Adresse des ersten Elements des Arrays), ArrayIndexscale (erhält die Inkrementadresse des Elements im Array).
Da der maximale Array -Wert von Java integer.max_Value ist, kann die Speicherzuweisungsmethode der unsicheren Klasse zur Implementierung super großer Arrays verwendet werden. Tatsächlich können solche Daten als C -Array angesehen werden, sodass Sie zur richtigen Zeit auf den freien Speicher achten müssen.
5. Multi-Thread-Synchronisation. Einschließlich Sperrmechanismus, CAS -Betrieb usw.
Dieser Teil umfasst MonitorEnter, TryMonitorenter, Monitorexit, VergleicheAnDSwapint, VergleicheSwap und andere Methoden.
Unter ihnen wurden MonitorExit, Trasmonitorenter und Monitorexit als veraltet markiert und werden nicht empfohlen.
Der CAS -Betrieb der unsicheren Klasse kann am meisten verwendet werden und bietet eine neue Lösung für Javas Schließmechanismus. Beispielsweise werden Atomicinder und andere Klassen mit dieser Methode implementiert. Die Vergleichs -WAP -Methode ist atomar, wodurch schwere Verriegelungsmechanismen vermieden und die Code -Effizienz verbessert werden können. Dies ist ein optimistisches Schloss, von dem in der Regel angenommen wird, dass es in den meisten Fällen keine Rennbedingung gibt, und wenn die Operation ausfällt, wird es weiterhin erneut versuchen, bis sie erfolgreich ist.
6. Suspend und wiederherstellen.
Dieser Teil umfasst Park, Unpark und andere Methoden.
Setzen Sie einen Faden durch die Parkmethode. Nach dem Rufen des Parks blockiert der Thread, bis Zeitüberschreitungs- oder Interrupt auftritt. Unpark kann einen ausstehenden Faden beenden, um ihn wieder normal zu machen. Der Suspend -Betrieb auf Threads im gesamten Parallelitäts -Framework ist in der Locksupport -Klasse eingekapselt. Es gibt verschiedene Versionen von Packmethoden in der LockSupport -Klasse, aber am Ende wird die unsichere Methode aufgerufen.
7. Speicherbarriere.
Dieser Teil umfasst Loadfence, Storefence, Fullfence und andere Methoden. Dies wird in Java 8 neu eingeführt, um Speicherbarrieren zu definieren, um eine Nachbestellung von Code zu vermeiden.
Loadfence () bedeutet, dass alle Lastvorgänge vor der Methode vor der Speicherbarriere abgeschlossen sind. In ähnlicher Weise bedeutet StoreFence (), dass alle Speichervorgänge vor dieser Methode vor der Speicherbarriere abgeschlossen sind. Fullfence () bedeutet, dass alle Last- und Speichervorgänge vor Abschluss der Methode vor der Speicherbarriere abgeschlossen sind.
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.