Maison  >  Article  >  Java  >  Qu’est-ce que l’échappement JVM ? Introduction aux principes de l'analyse d'échappement JVM

Qu’est-ce que l’échappement JVM ? Introduction aux principes de l'analyse d'échappement JVM

不言
不言avant
2018-10-08 14:58:593668parcourir

Ce que cet article vous apporte concerne l'évasion de la JVM ? L'introduction aux principes de l'analyse d'évasion JVM a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer, j'espère qu'elle vous sera utile.

Nous savons tous que les objets en Java sont alloués sur le tas par défaut. Dans la pile d'appels, seul le pointeur de l'objet est enregistré. Lorsqu'un objet n'est plus utilisé, il faut compter sur GC pour parcourir l'arborescence de référence et récupérer de la mémoire. S'il y a trop d'objets dans le tas, le recyclage des objets et l'organisation de la mémoire prendront du temps, GC sera soumis à une forte pression, ce qui affectera les performances. Par conséquent, dans notre développement quotidien, la mémoire et le temps sont très précieux. Comment optimiser la surcharge de la pile est une question relativement importante.

Ici, je parle de l'optimisation JVM du point de vue de l'analyse d'évasion.

Pourquoi « échapper »

Dans le principe de l'optimisation du compilateur de langage informatique, l'analyse d'échappement fait référence à la méthode d'analyse de la plage dynamique des pointeurs C'est la même chose que les principes d'optimisation du compilateur sont liés à l'analyse du pointeur et à l'analyse de la forme. Lorsqu'une variable (ou un objet) est allouée dans une méthode, son pointeur peut être renvoyé ou référencé globalement, qui sera référencé par d'autres méthodes ou threads. Ce phénomène est appelé échappement de pointeur (ou référence). En termes simples, si le pointeur d'un objet est référencé par plusieurs méthodes ou threads, alors nous appelons cela l'échappement du pointeur (ou de l'objet) de l'objet.

Un blogueur sur Internet a décrit escape de cette façon, en utilisant un code simple et direct, je pense que c'est assez simple et peut être utilisé à titre de référence :

public StringBuilder escapeDemo1(System a, System b) {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(a);
    stringBuilder.append(b);
    return stringBuilder;
}

stringBuilder est une variable interne. dans la méthode. À ce stade, il est renvoyé directement, donc stringBuilder peut être modifié par des méthodes ou des paramètres ailleurs, de sorte que sa portée ne soit pas seulement demo1. Bien qu'il s'agisse d'une variable locale, elle "s'est échappée".

Ensuite, je peux changer le code :

public String escapeDemo2(System a, System b) {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(a);
    stringBuilder.append(b);
    return stringBuilder.toString();
}

De cette façon, StringBuilder n'est pas renvoyé, mais toString(), alors StringBuilder n'est pas directement détaché de la méthode, et pas d'échappement se produit.

Qu'est-ce que l'analyse d'échappement

L'analyse d'échappement est un flux de données global interfonctionnel qui peut réduire efficacement la charge de synchronisation et la pression d'allocation du tas de mémoire dans les programmes Java. Analyse algorithme. Grâce à l'analyse d'échappement, le compilateur Java Hotspot peut analyser la plage d'utilisation de la référence d'un nouvel objet et décider s'il doit allouer cet objet au tas . Escape Analysis est actuellement une technologie d'optimisation relativement avant-gardiste dans les machines virtuelles Java.

Le principe de l'analyse d'échappement

Les propres limitations de Java (les objets ne peuvent être alloués que dans le tas), je peux le comprendre de cette façon, afin de réduire l'allocation d'objets temporaires dans le tas Le nombre, je définirai une variable locale dans un corps de méthode, et la variable ne s'échappera pas lors de l'exécution de la méthode. Selon le mécanisme de réglage JVM, une instance de la classe sera d'abord créée dans. la mémoire du tas, puis la référence de cet objet sera poussée dans la pile d'appels, continuez l'exécution, c'est la voie avant l'optimisation JVM. Ensuite, j'utilise l'analyse d'échappement pour optimiser la JVM. Autrement dit, pour la méthode de réallocation de la pile, recherchez d'abord la variable non échappée et stockez la variable directement sur la pile sans entrer dans le tas, une fois l'allocation terminée, continuez à appeler la pile pour l'exécution. se termine, l'espace de la pile est recyclé et les variables locales sont également recyclées. Cette opération s'effectue dans le tas avant l'optimisation et dans la pile après l'optimisation, réduisant ainsi l'allocation et la destruction d'objets dans le tas et optimisant les performances.

Moyens d'échappement

Méthode d'échappement : dans le corps d'une méthode, définissez une variable locale, qui peut être référencée par une méthode externe, par exemple transmise à une méthode en tant que paramètre d'appel ou renvoyé directement en tant qu'objet. Ou bien, on peut comprendre que l'objet sort de la méthode.

Échappement de thread : cet objet est accessible par d'autres threads, par exemple attribué à une variable d'instance et accessible par d'autres threads. L'objet a échappé au thread actuel.

Les avantages de l'analyse d'échappement

Si un objet ne s'échappe pas dans le corps de la méthode, ou s'échappe dans le thread (ou après avoir réussi l'analyse d'échappement, il ne se produit pas ) Échapper)

1. Allocation sur la pile

Généralement, les objets qui ne s'échappent pas occupent un espace relativement grand Si l'espace sur la pile peut être utilisé, un grand nombre d'objets le seront. être alloué avec la méthode. Détruit à la fin, réduisant la pression du GC

2.Élimination synchrone

S'il y a un verrou de synchronisation sur la méthode de la classe que vous définissez, mais au moment de l'exécution, uniquement. un thread y accède à ce moment-là. Le code machine après l'analyse d'échappement s'exécutera sans verrouillage de synchronisation.

3.Remplacement scalaire

Java虚拟机中的原始数据类型(int,long等数值类型以及reference类型等)都不能再进一步分解,它们可以称为标量。相对的,如果一个数据可以继续分解,那它称为聚合量,Java中最典型的聚合量是对象。如果逃逸分析证明一个对象不会被外部访问,并且这个对象是可分解的,那程序真正执行的时候将可能不创建这个对象,而改为直接创建它的若干个被这个方法使用到的成员变量来代替。拆散后的变量便可以被单独分析与优化,可以各自分别在栈帧或寄存器上分配空间,原本的对象就无需整体分配空间了。

开启设置

在JDK 6u23以上是默认开启,这里将设置重新明确一下:
强制开启:   

 -server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m

关闭逃逸分析:    

-server -XX:-DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m

写在结尾

栈上的空间一般而言是非常小的,只能存放若干变化和小的数据结构,无法存储大容量数据。目前的实现都是采用不那么准确但是时间压力相对较小的算法来完成逃逸分析,这就可能导致效果不稳定。所以,逃逸分析的效果只能在特定场景下,满足高频和高数量的小容量的变量分配结构,才是合适的。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer