Qual é a classe insegura?
O Java foi originalmente projetado como um ambiente controlado seguro. Apesar disso, o Java Hotspot ainda inclui um "backdoor" que fornece algumas operações de baixo nível que podem manipular diretamente a memória e os threads. Esta classe de backdoor - Sun.misc.unsfe - é amplamente usada em seus próprios pacotes pelo JDK, como java.nio e java.util.concurrent. No entanto, esse backdoor não é recomendado em ambientes de produção. Porque essa API é muito insegura, não leve e instável. Esta classe insegura fornece uma visão da estrutura interna da JVM do ponto de acesso e pode ser modificada. Às vezes, pode ser usado para aprender a estrutura interna da máquina virtual sem depuração de C ++ e, às vezes, pode ser usada como ferramentas de monitoramento e desenvolvimento de desempenho.
introdução
Recentemente, eu estava olhando para o código -fonte de pacotes simultâneos Java e descobri a classe mágica insegura. Estudei com cuidado e compartilhei com você aqui.
A classe insegura está sob o pacote Sun.Misc e não pertence ao padrão Java. No entanto, muitas bibliotecas básicas de classe Java, incluindo algumas bibliotecas de desenvolvimento de alto desempenho amplamente usadas, são desenvolvidas com base em classe insegura, como Netty, Cassandra, Hadoop, Kafka, etc. A classe insegura desempenha um grande papel na melhoria da eficiência da operação de Java e no aumento das capacidades de operação da linguagem Java.
A classe insegura dá a Java a capacidade de operar o espaço de memória como ponteiros na linguagem C e também traz problemas de ponteiro. O uso excessivo da classe insegura aumentará a chance de erros, para que o Java não o recomende ser usado e quase não há documentação oficial. O Oracle planeja remover a classe insegura do Java 9 e, se for esse o caso, seria muito grande.
Geralmente, é melhor não usar a classe insegura, a menos que tenha um objetivo claro e também tenha um entendimento profundo dela. Para usar a classe insegura, você precisa usar alguns métodos complicados. A classe insegura usa um padrão singleton e precisa ser obtido através de um método estático getUNSafe (). No entanto, a classe insegura a restringiu. Se for uma chamada normal, ele lançará uma exceção de segurança; Somente a classe carregada pelo carregador de classe principal pode chamar esse método. O código -fonte é o seguinte:
public static inseguro getUNSafe () {classe var0 = refletion.getCalerClass (); if (! vm.issystemdomainloader (var0.getclassloader ())) {lança a nova segurança ("inseguro"); } else {return theunsfe; }}Existem também algumas maneiras de carregar o código do usuário usando o carregador de classe principal, como definir o parâmetro BootClassPath. Mas a maneira mais simples é usar a reflexão Java, como segue:
Campo f = insefa.class.getDecLaredfield ("theunsfe"); f.SetAccessível (verdadeiro); Inseguro inseguro = (inseguro) f.get (nulo);Depois de obter a instância insegura, podemos fazer o que quisermos. A classe insegura fornece as seguintes funções:
1. Gerenciamento de memória. Incluindo alocar memória, liberar memória, etc.
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 semântica), PutInt (escreva o número inteiro no endereço de memória especificado), PutIntVolatile (escreva o número inteiro para o endereço de memória especificado e suporta semântica volátil), PutorderEdInt (escreva o número inteiro para o endereço de memória especificado, métodos ordenados ou atrasados). getxxx e putxxx contêm vários tipos básicos de operações.
Usando o método copimemory, podemos implementar um método geral de cópia de objeto sem implementar o método clone para cada objeto. Obviamente, esse método geral pode atingir apenas uma cópia superficial do objeto.
2. Instanciação do objeto não convencional.
O método alocateInstance () fornece outra maneira de criar uma instância. Normalmente, podemos instanciar objetos com nova ou reflexão. Use o método alocateInstance () para gerar diretamente instâncias de objetos sem os construtores de chamadas e outros métodos de inicialização.
Isso é útil ao desserializar objetos, permitindo a reconstrução e definição de campos finais sem os construtores de chamadas.
3. Classes de operação, objetos e variáveis.
Esta parte inclui o StaticFielfOffset (deslocamento do domínio estático), DefinClass (classe de definição), DefineanonyMousClass (classe anônima de definição), EnsureClassinitialized (Garanta a inicialização da classe), o ObjectFielfOffset (Offset de Domínio do Objeto) e outros métodos.
Através desses métodos, podemos obter o ponteiro do objeto. Ao compensar o ponteiro, não podemos apenas modificar diretamente os dados apontados pelo ponteiro (mesmo que eles sejam privados), mas também podemos encontrar objetos que a JVM já considerou lixo e pode ser reciclada.
4. Operação da matriz.
Esta parte inclui ArrayBaseoffset (obtém o endereço de deslocamento do primeiro elemento da matriz), ArrayIndexScale (obtém o endereço de incremento do elemento na matriz), etc. Arraybaseoffset é usado em conjunto com a ArrayIndexScale e você pode localizar a posição de cada elemento na matriz na memória.
Como o valor máximo da matriz de Java é inteiro.max_value, o método de alocação de memória da classe insegura pode ser usado para implementar matrizes super grandes. De fato, esses dados podem ser considerados uma matriz C; portanto, você precisa prestar atenção à libertação da memória no momento certo.
5. Sincronização com vários threads. Incluindo mecanismo de bloqueio, operação CAS, etc.
Esta parte inclui o MonitorEnter, TryMonitorEnter, Monitorexit, Comparanswapint, Comparanswap e outros métodos.
Entre eles, o MonitorEnter, o TryMonitorEnter e o monitorexit foram marcados como depreciados e não são recomendados.
A operação CAS da classe insegura pode ser mais usada e fornece uma nova solução para o mecanismo de bloqueio de Java. Por exemplo, o AtomicInteger e outras classes são implementadas por esse método. O método ComparaDSWAP é atômico, o que pode evitar mecanismos de travamento pesado e melhorar a eficiência do código. Este é um bloqueio otimista, que geralmente acredita -se que, na maioria dos casos, não haja condição de corrida e, se a operação falhar, continuará tentando novamente até que seja bem -sucedido.
6. suspender e restaurar.
Esta parte inclui parque, UMPK e outros métodos.
Suspenda um tópico pelo método do parque. Depois de ligar para o parque, o tópico bloqueará até que ocorra o tempo limite ou interrupção. O UMPARK pode encerrar um encadeamento pendente para restaurá -lo ao normal. A operação de suspensão nos threads em toda a estrutura de simultaneidade é encapsulada na classe LockSupport. Existem várias versões dos métodos de embalagem na classe LockSupport, mas no final, o método inseguro.park () é chamado.
7. Barreira de memória.
Esta parte inclui Loadfence, Storefence, Fullfence e outros métodos. Isso é introduzido recentemente no Java 8 para definir barreiras de memória para evitar a reordenação do código.
loadfence () significa que todas as operações de carga antes do método são concluídas antes da barreira da memória. Da mesma forma, StoreFence () significa que todas as operações da loja antes desse método são concluídas antes da barreira da memória. Fullfence () significa que todas as operações de carga e loja antes do método são concluídas antes da barreira da memória.
Resumir
O acima é o conteúdo inteiro deste artigo. Espero que o conteúdo deste artigo tenha certo valor de referência para o estudo ou trabalho de todos. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar. Obrigado pelo seu apoio ao wulin.com.