Technology sharing

Articulus scientia popularis: Intellige pugnam actualem de jvm in uno articulo (4) In profunditate intellectus effugii analysis Analysis

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Overview

An res in Java in memoriam cumulo partita sint?

Bene, nimis abstractum est. Eamus subtilius.

  1. public void test() {
  2. Object object = new Object();
  3. }
  4. 这个方法中的object对象,是在堆中分配内存么?

Dic eventum: rem deducant memoriam in acervo vel in cumulo.

Hic punctum cardinis est: In exsequenda JVM, ut perficiendum JVM et spatium memoriae ad corrigendum, JVM praebet pluma quae "analysis effugiat" Java machina virtualis, et est etiam JIT ars magni ponderis optimization. jdk6 solum hanc technologiam inducere coepit, jdk7 incepit ut analysis effugium per defaltam faceret, jdk8 analysin evadere coepit, et per defaltam usque JDK 9, evasionis analysis adhibebitur ut methodus optimizatione default et nulla compilatio parametri specialis requiruntur.

Nunc intellige sententiam "obiectum ut memoriam in acervo vel memoriam collocare in acervo" Solus Analysis Effugere coepit sustentari; jdk9 maxime probabile est ACERVUM (obiectum hic perexiguum), quod jdk9 solum vere sustinet et efficit ut analysin effugiat per defaltam.

Cum evolutione compilariorum JIT (modo-in-temporis compilatores) et paulatim maturitas technologiae analyseos evadendi, ACERVUS destinatio et scalaris technologiae optimization reponenda causa erit "omnia res in acervo collocabuntur" ut minus absoluta fiant machina virtualis, quae objecta memoriae in acervo collocantur, sed est casus specialis, hoc est, si post analysin evadat inveniatur objectum non evadat ex modo, in acervo collocari potest optimized. Cum modus exsecutus est Cum completur, corpus acervus papaver et obiectum solvitur. Hoc excludit necessitatem ut memoriam in acervo collocant et collectionem purgamentum subeunt.Hotspot non currently hoc faciunt).

Post JDK 6u23 (memorabilis versio maioris JDK7), analysin effugium potest per default in Hotspot. Visum colum eventum ad analysin effugiendam.

Hotspot instrumentum scalaris per analysin effugium reponitur (obiecta non-effugia reponuntur cum scalaribus et aggregatis, quae codicem efficientiam emendare possunt), sed res non-efugient adhuc memoriam in acervo collocant, ideo adhuc dici potest omnia obiecta collocare. memoriam cumulo.

Praeterea, penitus nativus secundum Open JDKTaoBao VM, inter quas porttitor GCIH (GC acervus invisibilis) instrumentorum technologicorum extemporalitatis, objecta mobilia cum cyclis longis vitae ab acervo usque ad extra cumulum, et GC non administrat Java objecta intra GCIH, inde reducendo GC frequentiam redivivus et ad propositum emendandum. GC recuperatio efficientia.

Stack: Cum utraque methodus exequatur, tabula ACERVUS creabitur simul ad informationes congregendas ut mensas variabiles locales, acervos operationes, nexus dynamicas, exitus modus, etc. Processus ab unaquaque methodo vocatus donec exsecutio perficiatur, respondet processui e ACERVI in ACERVUS trudi ad papaver e e ACERVUS in ACERVUS virtualis apparatus.

Tumulus;Cum res instantiatur, res in acervum collocatur et respectus ad acervum emittitur in acervum.

effugere;Cum monstratorem rei multiplicis methodi vel filis designant, dicimus regulam evadere. Fere res reddere et variabiles globales plerumque evadere.

Effugere analysin:Modus usus ad analysim hanc phaenomenon effugium vocatur analysin effugium

Effugere analysin optimization - destinatio in acervum:Destinatio in ACERVUS significat instantiam ab loci variabili in modo generatam (nihil evasionis occurrit) in acervum collocari et in acervo collocari non oportet. Denique, sequela terminatur, ACERVUS spatium REDIVIVUS EST, et localia variabilia etiam REDIVIVUS sunt.

Java object memoriae destinatio processus

  1. Si destinatio in ACERVUS (analysis evasionis) possit, JVM primum in acervum collocabit.
  2. Si destinatio in ACERVUS non datur vel condiciones non convenerunt, destinatio TLAB inseretur.
  3. Si destinatio TLAB parum succedit an varius, utrum destinatio generationis ingredi possit.
  4. Si autem veterem generationem non potest introire, destinatio voluptatis intrabit.
  5. Non omnia in acervum collocantur. Praeter acervum, res etiam in acervum et TLAB collocari potest. (Plerique collocantur in acervo)

An res in Java in acervo necessario partita sint?

Responsio: Non necessario.

Si condiciones analysis effugii occurrerunt, obiectum ACERVUS collocari potest.Reducere acervum memoriae destinatio et GC pressio.Cum memoria ACERVUS limitatur, si res occurrat condiciones scalaris subeuntibus;Additur operatio in re frangere partes.Substitutio scalaris modus specificus est: JVM obiectum ulterius dissolvet et rem in plures variabiles membri usus hac methodo dissolvet.Sic finis melioris usus e actis memoriae ac registris obtinetur.

Quomodo obiecti in acervum collocare ad acervum analysin effugium requirit.

Haec est crux-munus globalis notitiae analyseos algorithm fluunt, qui efficaciter synchronization onus minuere et memoriam pressionis pressionis in Java programmate congerunt. Per analysim effugiendam, Java Hotspot compilator usum extensionis novi propositi obiecti resolvere potest et dijudicare an hoc obiectum cumulo collocare.

Mores fundamentales analysi evadendi est resolvere dynamicum objectorum ambitum;

  1. Cum objectum in methodo definitur et obiectum solum intra modum adhibetur, consideratur evasionem nullam incidisse.
  2. Objectum methodo definitur ac per modum externum refertur, evasio fit. Exempli gratia, omittitur modulus ad alia loca.

In computatrum linguarum auctor ipsum principium, analysin effugium refertur ad modum examinandi dynamicam notarum notarum. Cum in methodo variabilis (vel objectum) partita sit, monstrator eius globally vel referenced reddi potest, quod ab aliis modis vel sequelis referetur. In verbis laicalis, si regula objecti multiplicibus modis vel filis referatur, vocamus obiecti regulam (vel objectum) Effugere (quia hoc tempore obiectum fugit methodus seu stamina localia).

Quid est analysis effugium?

Brevis descriptio: "Analysis evase: Analysis stabilis quae dynamicam range monstrantium determinat. Dispicere potest ubi in programmatis regula accedere potest." noviter creatum objectum evasit.

Fundamentum iustorum in tempore compilatio est determinare an res evadat: una est an res condita in acervo (campo statico an instantia agri obiecti in acervo), et alterum est an res in acervum transferatur. codice ignoto.

Analysis effugia in praesenti technologiae optimizationis extremitatem relativam in machinis virtualis Java.

Effugere Analysis: technologiam optimam JIT magni momenti est, ad deliberandum an accessura sit obiecti extra modum, hoc est, ut modus evadat. Effugere analysin est gradus JIT compilatoris. Per JIT possumus determinare quae res intra modum utendi restrictae sunt et ad extra non evadent . Aut scalare substituendo praestare objectum scindendi in multiplices formas fundamentales pro repono. Crux-munus globalis notitiae analyseos algorithm influunt, qui efficaciter synchronisationi onus et memoriam reducere possunt, prouinciis et pressuris collectionis purgamentorum in programmatis Javae. Per analysim effugiendam, Java Hotspot compilator usum extensionis novi propositi obiecti resolvere potest et dijudicare an hoc obiectum cumulo collocare.

Analysis elapsus maxime spectat ad variabiles locales ad determinandum an objecta in acervo partita methodi scopum evaserint. Iungitur analysi monstrante ac figura analysi compilator optimizationis principiorum. Cum in methodo variabilis (vel objectum) partita sit, monstrator eius globally vel referenced reddi potest, quod ab aliis modis vel sequelis referetur. In verbis laicalis, si regula objecti multiplicibus modis vel filis refertur, tunc dicimus objectum monstratorem evasisse. Proprie designans codicem structuram et usus notitiae melius uti potest effugium analysin ad optimize progressionis effectum. Caput etiam reducere possumus obiectis collocandis in cumulo et ad meliorem memoriam utendo per analysim effugiendam.

Effugere analysin est ars adhibenda ad determinandum an res extra ambitum methodi in vita sua evaserit. In Java evolutione, analysi effugia adhibetur ad determinandam vitam cycli et ambitum objectorum ad perficiendum debitam optimam et meliorem programmata perficiendi et memoriae utendi efficientiam.

Cum res creata est, intra methodum adhiberi potest, vel ad alios modos vel fila transiri et extra modum subsistere. Si obiectum methodi ambitum non effugit, JVM in acervum pro acervo collocare potest, ita supra caput acervi memoriae destinatio et purgamentum collectionis evitatur.

  1. 关于逃逸分析的论文在1999年就已经发表,但直到Sun JDK 1.6才实现了逃逸分析,而且直到现在这项优化尚未足够成熟,仍有很大的改进余地。不成熟的原因主要是不能保证逃逸分析的性能收益必定高于它的消耗。如果要完全准确的判断一个对象是否会逃逸,需要进行数据流敏感的一系列复杂分析,从而确定程序各个分支执行时对此对象的影响。这是一个相对高耗时的过程,如果分析完后发现没有几个不逃逸的对象,那这些运行期耗用的时间就白白浪费了,所以目前虚拟机只能采用不那么准确,但时间压力相对较小的算法来完成逃逸分析。还有一点是,基于逃逸分析的一些优化手段,如上面提到的“栈上分配”,由于HotSpot虚拟机目前的实现方式导致栈上分配实现起来比较复杂,因此在HotSpot中暂时还没有做这项优化。
  2. 在测试结果中,实施逃逸分析后的程序在MicroBenchmarks中往往能运行出不错的成绩,但是在实际的应用程序,尤其是大型程序中反而发现实施逃逸分析可能出现效果不稳定的情况,或因分析过程耗时但却无法有效判别出非逃逸对象而导致性能(即使编译的收益)有所下降,所以在很长的一段时间里,即使是Server Compiler,也默认不开启逃逸分析(在JDK 1.6 Update 23的Server Compiler中才开始默认开启了逃逸分析),甚至在某些版本(如JDK 1.6 Update 18)中还曾经短暂的完全禁止了这项优化。
  3. 如果有需要,并且确认对程序运行有益,用户可以使用参数-XX:+DoEscapeAnalysis来手动开启逃逸分析,开启之后可以通过参数-XX:+PrintEscapeAnalysis来查看分析结果。有了逃逸分析支持之后,用户可以使用参数-XX:EliminateAllocations来开启标量替换,使用+XX:+EliminateLocks来开启同步消除,使用参数-XX:PrintEliminateAllocations查看标量的替换情况。
  4. 尽管目前逃逸分析的技术仍不是十分成熟,但是他却是即时编译器优化技术的一个重要的方向,在今后的虚拟机中,逃逸分析技术肯定会支撑起一系列使用有效的优化技术。

Prima principia effugia analysis

Principium fundamentale JVM analysis effugium est determinare condicionem rei per duas methodos analysin: static et dynamicam.

In systemate Iava compilation, processus vertendi a fonte codicis lima Javae in instructionem machinae computatrum exsecutabilis duos gradus compilations requirit:

Prima compilatio sectio refertur ad ante-finem compilator.java fileconversus est.class file (bytecode file). Ante-finem compilator productorum Javac JDK vel compilator incrementi in Eclipse JDT esse potest.

In secundo scaena compilation, JVM bytecode interpretatur et eum in respondens machinae instructiones vertit, in bytecode singulatim legit, et in codicem machinae interpretatur et vertit.

Uti patet, propter intermedium interpretationis processum, eius celeritas exsecutionis inevitabiliter multo tardius erit quam progressio binarii exsecutabilis bytecode. Hoc munus est JVM interpretis traditi (Interpres).

Quomodo medios viros exscindere et efficaciam emendare?

Ad solvendam hanc quaestionem efficientiam, JIT (Just In Time Compiler) technologia introducta est.

Post introductionem technologiarum JIT, programmata Java usque per interpretem interpretata et exsecuta sunt. Hoc est, agmen adhuc interpretatum et supplicium est, sed intermedia nexus ex parte removentur.

JIT Compiler (Just-in-timeCompiler) in tempore compilatio. Prima exsequendi solutio Javae constabat ex instituto interpretum (interpretum) qui singulas Javas instructiones in microprocessoris aequivalens instructionis interpretati sunt et eas continue secundum ordinem mandatorum translati exsecuti sunt, quia institutio Java in duodecim vel justos transferri potuit. equivalent microprocessor instructiones, hic modus tardissime exequitur.

Quomodo nexus intermedios partim tollere?

Cum in JVM reperit certam methodum seu impedimentum codicem praecipue currendum esse, considerabit illam esse "Hot Spot Code". Tunc JIT partem "calidi Codicis" in machinam ad machinae localem pertinentem transferet, optimize illum, et dein machinae translatae codicem pro proximo usui condito.

Ubi est machinae translatae codicem emittere? Hoc cache dicitur Codex Cache. Videri potest rationes ad altam concurrentiam inter JVM et WEB applicationes assequendi similes esse, et architectura cache adhuc utuntur.

Cum in JVM in eodem codice calido iterum occurrit, nexum intermedium interpretationis transmittit, machinam codicem directe e Codice Cache onerat, idque protinus sine denuo componendo exercet.

Finis ergo altiore JIT est ut codicem calidum invenias, et in codice calido clavem ad meliorationem effectus factus est. Hoc modo nomen JVM hotspot factum est.

Suprema igitur militarium JVM est;

  • In plerisque codicibus non vulgaribus, non opus est ut eos in apparatus codicem congero, sed per interpretationem et executionem percurramus;

  • Ex altera parte, pro codice calido, qui parvam tantum partem obtinet, eum in machinae codicem compilare possumus ad specimen celeritatis currentis consequendum.

Cessus JIT (modo in tempore compilatio) et differentia inter interpretes

(1) Interpres bytecode in machinam codicem interpretatur.

(2) JIT aliquos bytecodes in machinas conficit et eos in Codice Cache reponit.

(3) Interpres interpretatur bytecode in machina codicem, qui est omnibus suggestus communis.

(4) JIT codicem machinae specificae suggestum generabit e suggestu typum.

JVM multiplex in tempore compilatores, praesertim C1 et C2, et Graal (experimentalis) continet.

Multiplex iustus-in-tempus compilatores optimize in bytecode et generare apparatus codicem

  • C1 optimizationem simplicem et certam de bytecode, incluso methodo inliniendi, de-virtualizationis, redundantiae eliminationis, etc. Compilatio celeritas celerior est.
  • C2 optimizationes radicales in bytecode, incluso ramo frequentiae praenuntiationis, synchronae rasurae, etc. C2 compilationem cogi possunt per -servatorem definiri.

JVM exsecutionem status dividit in 5 gradus;

  • Level 0, Interpres

  • Level I, exaravit et profecit per C1 iustus-in-vicis compilator (sine profiling)

  • Layer II, C1 iustus-in-vicis compilator compilavit et exsecutus est usus (cum basic profiling)

  • Layer III, C1 iustus-in-vicis compilator compilavit et prosecutus est utens (cum completum profiling)

  • Level IV, C2 iustus-in-tempus compilator compilavit et exsecutioni mandare usura

JVM non directe efficiat C2.

In modo compilation, machina virtualis exsecutionis status in quinque stratis a simplici ad complexum, a ieiunio ad tardum dividitur.

In compilatione, praeter codicem calidum caching ad processum accelerandum, JIT multas optimizationes in codice etiam faciet.

Ad aliquas optimizations estReduce memoriam tumulus destinatio pressura una ex magnis artificiis in JIT optimization vocatur analysis effugium. Secundum analysin effugiendam, compilator iustus in tempore codicem optimizet ut sequitur in processu compilation:

  • Clausura eliminationis: Cum cincinno obiectum uno tantum filo claudatur, iustus in tempore compilator crinem auferet.
  • Destinatio in ACERVUS: Objectum cum non effugit, obiectum directe in acervum collocabitur. sed reposito scalari utitur.
  • Repositum scalare: Cum obiectum non effugit, obiectum praesens frangetur in plures variabiles locales et collocatur in mensa locali variabilis ACERVUS machinae virtualis.

1. Analysis Static est analysis tempore compilare

Inhibet stabilitatem codicis structuram determinare an obiectum possit evadere. Exempli gratia, cum aliquid alicui membro variabili ordinis assignatur, aut in externum modum revertitur, determinari potest rem fugientem.

2. Analysis Dynamic fit in analysis runtime

Decernit an objectum vitet observando mores methodi vocat et objectum indiciorum. Exempli causa, cum res multiplici fila referatur, objectum evasisse judicari potest.

Analysis evasio peragit in altissimam analysin codicis ad determinandum an objectum evaserit extra methodi scopo in methodo vivente. Si obiectum non effugit, JVM in acervum pro acervo collocare potest.

Effugere statum: effugium globalis, parametri effugium, nullum effugium

Objectum tres civitates effugium habet: effugium globalis, parametri effugium, et nullum effugium.

global effugium(GlobalEscape): Id est, scopus obiecti e methodo currenti seu filo currenti evadit.

Fere sunt sequentes missiones;
① Obiectum est stabili variabilis
Obiectum est obiectum fugit
③ Obiectum reditus ad valorem current modum adhibetur ut

Parameter effugium(ArgEscape): Id est, objectum pro modulo parametri seu per modulum referente transmittitur, sed nulla evasio globalis fit in processu vocationis. Hic status a bytecode vocati methodi determinatur.

non effugiumId est rem ratione non fugit.

Status fugae specimen codice talis est:

  1. public class EscapeAnalysisTest {
  2. public static Object globalVariableObject;
  3. public Object instanceObject;
  4. public void globalVariableEscape(){
  5. globalVariableObject = new Object(); // 静态变量,外部线程可见,发生逃逸
  6. }
  7. public void instanceObjectEscape(){
  8. instanceObject = new Object(); // 赋值给堆中实例字段,外部线程可见,发生逃逸
  9. }
  10. public Object returnObjectEscape(){
  11. return new Object(); // 返回实例,外部线程可见,发生逃逸
  12. }
  13. public void noEscape(){
  14. Object noEscape = new Object(); // 仅创建线程可见,对象无逃逸
  15. }
  16. }

Modi effugium: methodus effugium et filum effugium


1. Methodus evadendi: In methodo corporis, localem variabilem definire, quae methodo externa referri potest, ut ad modum vocationis parametri, vel directe ut objecti revertitur. Vel potest intelligi quod res prosilit per modum.

Modus fugit includit:

  • Obiectum electronicum praetermitte aliis modis parametri vocando;
  • Obiectum redit monstratorem aliis modis per reditum constitutionis
  • etc.
  1. 我们可以用下面的代码来表示这个现象。
  2. //StringBuffer对象发生了方法逃逸
  3. public static StringBuffer createStringBuffer(String s1, String s2) {
  4. StringBuffer sb = new StringBuffer();
  5. sb.append(s1);
  6. sb.append(s2);
  7. return sb;
  8. }
  9. 上面的例子中,StringBuffer 对象通过return语句返回。
  10. StringBuffer sb是一个方法内部变量,上述代码中直接将sb返回,这样这个StringBuffer有可能被其他方法所改变,这样它的作用域就不只是在方法内部,虽然它是一个局部变量,称其逃逸到了方法外部。
  11. 甚至还有可能被外部线程访问到,譬如赋值给类变量或可以在其他线程中访问的实例变量,称为线程逃逸。
  12. 不直接返回 StringBuffer,那么StringBuffer将不会逃逸出方法。
  13. 具体的代码如下:
  14. // 非方法逃逸
  15. public static String createString(String s1, String s2) {
  16. StringBuffer sb = new StringBuffer();
  17. sb.append(s1);
  18. sb.append(s2);
  19. return sb.toString();
  20. }
  21. 可以看出,想要逃逸方法的话,需要让对象本身被外部调用,或者说, 对象的指针,传递到了 方法之外。

Quomodo cito determinare potest utrum analysis effugium acciderit? Inspiciamus an novum ens ens extra modum dicatur.

  1. public class EscapeAnalysis {
  2.  
  3.     public EscapeAnalysis obj;
  4.  
  5.     /**
  6.      * 方法返回EscapeAnalysis对象,发生逃逸
  7.      * @return
  8.      */
  9.     public EscapeAnalysis getInstance() {
  10.         return obj == null ? new EscapeAnalysis():obj;
  11.     }
  12.  
  13.     /**
  14.      * 为成员属性赋值,发生逃逸
  15.      */
  16.     public void setObj() {
  17.         this.obj = new EscapeAnalysis();
  18.     }
  19.  
  20.     /**
  21.      * 对象的作用于仅在当前方法中有效,没有发生逃逸
  22.      */
  23.     public void useEscapeAnalysis() {
  24.         EscapeAnalysis e = new EscapeAnalysis();
  25.     }
  26.  
  27.     /**
  28.      * 引用成员变量的值,发生逃逸
  29.      */
  30.     public void useEscapeAnalysis2() {
  31.         EscapeAnalysis e = getInstance();
  32.     }
  33. }

2. Filum effugium: Obiectum hoc ab aliis sequelis accessum, ut instantia variabili attributa et ab aliis stamina accessa. Obiectum stamen fugit.

Optimization consilia evadere analysis

Effugere analysin possunt sequentes rationes optimae rationes ad Java programmata: destinatio in acervum, synchronisation eliminationem, repositum scalare, et methodum inlinendi;

Effugere analysin parametri cognata:

  1. -XX:+DoEscapeAnalysis 开启逃逸分析
  2. -XX:+PrintEscapeAnalysis 开启逃逸分析后,可通过此参数查看分析结果。
  3. -XX:+EliminateAllocations 开启标量替换
  4. -XX:+EliminateLocks 开启同步消除
  5. -XX:+PrintEliminateAllocations 开启标量替换后,查看标量替换情况。

1. Stack Destinatio

Analysis elabi potest uter objecta methodi scopum non effugiet, et haec in acervo loco acervi collocant. Res in ACERVUS partita creantur et destruuntur intra modum vocationis cycli vitae sine purgamento collectionis, ita programma exsecutionis efficientiae melioris.

In communi rerum adiunctis, quae effugere non possunt, magnum spatium relative occupant. Si spatium in acervo adhiberi potest, numerus obiecti destruetur cum methodus desinat, GC pressione reducendo.

        Destinatio notiones in ACERVUSDestinatio in ACERVUS est technologiae optimiizationis a JVM comparatae.
Idea est;

  1. Obiecta enim fila privata (obiecta quae ab aliis filis accedere non possunt), collocari possunt memoriam pro acervo memoriae cumulo, quae solutio est aggregatum variabilium cum scalaribus reponere.
  2. Commodum in ACERVUS partita est ut statim destrui possit post modum finium, sine necessitate GC interventu, ratio perficiendi meliori.
  3. Multis obiectis dispersis, destinatio in acervum bonum destinatio belli praebet.

Problema: Cum ACERVUS memoria relative parva sit, res magnae non possunt nec non sunt aptae in ACERVUS.
        Admitte in BIBLIOTHECA destinatio
Destinatio in ACERVUS fundatur in analysis evasionis et reponenda scalari, ut analysin effugiat et substitutio scalaris efficiatur. Scilicet, JDK1.8 per default.

  1. 开启逃逸分析:-XX:+DoEscapeAnalysis
  2. 关闭逃逸分析:-XX:-DoEscapeAnalysis
  3. 显示分析结果:-XX:+PrintEscapeAnalysis
  4. 开启标量替换:-XX:+EliminateAllocations
  5. 关闭标量替换:-XX:-EliminateAllocations
  6. 显示标量替换详情:-XX:+PrintEliminateAllocations

Exemplum destinatio in ACERVUS:

  1. 示例1
  2. import java.lang.management.ManagementFactory;
  3. import java.util.List;
  4. /**
  5. * 逃逸分析优化-栈上分配
  6. * 栈上分配,意思是方法内局部变量(未发生逃逸)生成的实例在栈上分配,不用在堆中分配,分配完成后,继续在调用栈内执行,最后线程结束,栈空间被回收,局部变量对象也被回收。
  7. * 一般生成的实例都是放在堆中的,然后把实例的指针或引用压入栈中。
  8. *虚拟机参数设置如下,表示做了逃逸分析 消耗时间在10毫秒以下
  9. * -server -Xmx10M -Xms10M
  10. -XX:+DoEscapeAnalysis -XX:+PrintGC
  11. *
  12. *虚拟机参数设置如下,表示没有做逃逸分析 消耗时间在1000毫秒以上
  13. * -server -Xmx10m -Xms10m
  14. -XX: -DoEscapeAnalysis -XX:+PrintGC
  15. * @author 734621
  16. *
  17. */
  18. public class OnStack{
  19. public static void alloc(){
  20. byte[] b=new byte[2];
  21. b[0]=1;
  22. }
  23. public static void main(String [] args){
  24. long b=System.currentTimeMillis();
  25. for(int i=0;i<100000000;i++){
  26. alloc();
  27. }
  28. long e=System.currentTimeMillis();
  29. System.out.println("消耗时间为:" + (e - b));
  30. List<String> paramters = ManagementFactory.getRuntimeMXBean().getInputArguments();
  31. for(String p : paramters){
  32. System.out.println(p);
  33. }
  34. }
  35. }
  36. 加逃逸分析的结果
  37. [GC (Allocation Failure) 2816K->484K(9984K), 0.0013117 secs]
  38. 消耗时间为:7
  39. -Xmx10m
  40. -Xms10m
  41. -XX:+DoEscapeAnalysis
  42. -XX:+PrintGC
  43. 没有加逃逸分析的结果如下:
  44. [GC (Allocation Failure) 3320K->504K(9984K), 0.0003174 secs]
  45. [GC (Allocation Failure) 3320K->504K(9984K), 0.0002524 secs]
  46. 消耗时间为:1150
  47. -Xmx10m
  48. -Xms10m
  49. -XX:-DoEscapeAnalysis
  50. -XX:+PrintGC
  51. 以上测试可以看出,栈上分配可以明显提高效率: 效率是不开启的1150/7= 160
  52. 示例2
  53. 我们通过举例来说明 开启逃逸分析 和 未开启逃逸分析时候的情况
  54. class User {
  55. private String name;
  56. private String age;
  57. private String gender;
  58. private String phone;
  59. }
  60. public class StackAllocation {
  61. public static void main(String[] args) throws InterruptedException {
  62. long start = System.currentTimeMillis();
  63. for (int i = 0; i < 100000000; i++) {
  64. alloc();
  65. }
  66. long end = System.currentTimeMillis();
  67. System.out.println("花费的时间为:" + (end - start) + " ms");
  68. // 为了方便查看堆内存中对象个数,线程sleep
  69. Thread.sleep(10000000);
  70. }
  71. private static void alloc() {
  72. // 未发生逃逸
  73. User user = new User();
  74. }
  75. }
  76. 设置JVM参数,表示未开启逃逸分析
  77. -Xmx1G -Xms1G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails
  78. 花费的时间为:664 ms
  79. 然后查看内存的情况,发现有大量的User存储在堆中
  80. 开启逃逸分析
  81. -Xmx1G -Xms1G -XX:+DoEscapeAnalysis -XX:+PrintGCDetails
  82. 然后查看运行时间,我们能够发现花费的时间快速减少,同时不会发生GC操作
  83. 花费的时间为:5 ms
  84. 在看内存情况,我们发现只有很少的User对象,说明User未发生逃逸,因为它存储在栈中,随着栈的销毁而消失。

Per comparationem videre possumus

  • In ACERVUS destinatio converte et obiecta in acervum memoriam non effugisse collocant, quae manifesto efficacius currunt.
  • Postquam destinatio in acervum occlusa est, GC saepe purgamentum collectionis facit.

2. Obfirmo Eliminationis

Analysis elabi potest deprehendere quaedam obiecta solum unico filo accessi et ad alia fila non evadunt. Ideo operationes supervacaneae synchronisation tolli possunt et exsecutio supra caput multi- plicatorum programmatum reducitur.

Comae synchronisation valde edax peractio sunt, itaque compilator rem non fugit, synchronizationem obiecto ab obiecto removebit. JDK1.8 Synchronisation comas per defaltam facit, sed fundatur ut analysin effugiat.

  1. -XX:+EliminateLocks #开启同步锁消除(JVM默认状态)
  2. -XX:-EliminateLocks #关闭同步锁消除
  1. 通过示例: 明显可以看到“逃逸分析和锁消除” 对性能的提升
  2. public void testLock(){
  3. long t1 = System.currentTimeMillis();
  4. for (int i = 0; i < 100_000_000; i++) {
  5. locketMethod();
  6. }
  7. long t2 = System.currentTimeMillis();
  8. System.out.println("耗时:"+(t2-t1));
  9. }
  10. public static void locketMethod(){
  11. EscapeAnalysis escapeAnalysis = new EscapeAnalysis();
  12. synchronized(escapeAnalysis) {
  13. escapeAnalysis.obj2="abcdefg";
  14. }
  15. }
  16. 设置JVM参数,开启逃逸分析, 耗时:
  17. java -Xmx64m -Xms64m -XX:+DoEscapeAnalysis
  18. 设置JVM参数,关闭逃逸分析, 耗时:
  19. java -Xmx64m -Xms64m -XX:-DoEscapeAnalysis
  20. 设置JVM参数,关闭锁消除,再次运行
  21. java -Xmx64m -Xms15m -XX:+DoEscapeAnalysis -XX:-EliminateLocks
  22. 设置JVM参数,开启锁消除,再次运行
  23. java -Xmx64m -Xms15m -XX:+DoEscapeAnalysis -XX:+EliminateLocks

Sumptus sequelae synchronisation satis altus est, et consecutio synchronisationum concursus et effectus reducitur.

Cum dynamice componendo scandalum synchronisatum, compilator JIT analysi effugium uti potest ad determinare num clausura objecti a synchronisedo clausula nonnisi uno filo accessi potest et ad alia fila dimissa non est. Sin minus, compilator JIT hanc codicis partem desynchronizet cum stipitem hanc synchronizatam componendo. Hoc concursus et effectus multum emendare possunt. Hic processus synchronisation cassandi synchronisation omissio dicitur, etiam lock eliminatio.

  1. 例如下面的代码
  2. public void f() {
  3.     Object hellis = new Object();
  4.     synchronized(hellis) {
  5.         System.out.println(hellis);
  6.     }
  7. }
  8. 代码中对hellis这个对象加锁,但是hellis对象的生命周期只在f()方法中,并不会被其他线程所访问到,所以在JIT编译阶段就会被优化掉,优化成:
  9. public void f() {
  10.     Object hellis = new Object();
  11.     System.out.println(hellis);
  12. }
  13. 我们将其转换成字节码,此处发现,还是有同步锁的身影,是因为优化是在编译阶段的,在加载进内存后发生。

3. Scalar Replacement

Analysis effugia rem in plures scalares dividere potest, ut species primitivae vel alia obiecta, easque in diversis locis assignare. Hoc memoriam minuere potest ruptionis et obiecti accessum supra caput, et utens efficiendi memoriam emendare.

Imprimis scalares et aggregationes intelligendae sunt. Quantitas ulterius dissolvi potest, est quantitas aggregata, ut: obiectum.

Obiectum est quantitas aggregata, quae ulterius in scalares et membrum eius variabiles in variabiles discretas dissolvi potest.

Hoc modo, si res non evadat, omnino opus non est.

Substitutio scalaris etiam per defaltam in JDK1.8 data est, sed etiam fundata est ut possit evadere analysis.

Scala est notitia quae in minores notitias rescindi non potest. Primitiva notitia generis in Java scalari est.

E contra, notitia quae componi potest, aggregatum dicitur.

  1. public static void main(String args[]) {
  2.     alloc();
  3. }
  4. class Point {
  5.     private int x;
  6.     private int y;
  7. }
  8. private static void alloc() {
  9.     Point point = new Point(1,2);
  10.     System.out.println("point.x" + point.x + ";point.y" + point.y);
  11. }
  12. 以上代码,经过标量替换后,就会变成
  13. private static void alloc() {
  14.     int x = 1;
  15.     int y = 2;
  16.     System.out.println("point.x = " + x + "; point.y=" + y);
  17. }

In scaena JIT, si per analysin evadat deprehenditur objectum extra mundum non accedere, tum post ipsum JIT, res in plures variabiles in eo contentas et reponendas congregabitur. Hic processus reponenda scalaris est.
Videri potest quod, post analysim effugiendam, inventum est quantitatem aggregatam Point non effugisse, ita duobus scalaribus substitutum est. Quaenam igitur sunt scalae substitutionis beneficia? Hoc est, in memoriam acervum redigere mire reperias. Quia semel non est opus ad res creatas, non est opus ad memoriam congerere collocare. Substitutio scalaris bonam fundamentum praebet ad destinationem in acervo.

Effugere analysis temptationis

  1. 逃逸分析测试
  2. 代码如下,大致思路就是 for 循环 1 亿次,循环体内调用外部的 allot() 方法,而 allot() 方法的作用就是简单创建一个对象,但是这个对象是内部的,所以是未逃逸的,所以理论上 JVM 是会进行优化的,我们拭目以待。并且我们会对比开启和关闭逃逸分析之后各自程序的运行时间:
  3. /**
  4. * @ClassName: EscapeAnalysisTest
  5. * @Description: http://www.jetchen.cn 逃逸分析 demo
  6. * @Author: Jet.Chen
  7. * @Date: 2020/11/23 14:26
  8. * @Version: 1.0
  9. **/
  10. public class EscapeAnalysisTest {
  11. public static void main(String[] args) {
  12. long t1 = System.currentTimeMillis();
  13. for (int i = 0; i < 100000000; i++) {
  14. allot();
  15. }
  16. long t2 = System.currentTimeMillis();
  17. System.out.println(t2-t1);
  18. }
  19. private static void allot() {
  20. Jet jet = new Jet();
  21. }
  22. static class Jet {
  23. public String name;
  24. }
  25. }
  26. 上面就是我们进行逃逸分析测试的代码, mian() 方法末尾有一个线程暂停,目的是为了观察此时 JVM 中的内存情况。
  27. Step 1:测试开启逃逸
  28. 由于环境是 jdk1.8,默认开启了逃逸分析,所以直接运行,得到结果如下,程序耗时 3 毫秒:
  29. 此时线程是处于睡眠状态的,我们观察下内存情况,发现堆内存中一共新建了 11 万个 Jet 对象。
  30. Step 2:测试关闭逃逸
  31. 我们关闭逃逸分析再来运行一次(使用 java -XX:-DoEscapeAnalysis EscapeAnalysisTest 来运行代码即可),得到结果如下,程序耗时 400 毫秒:
  32. 此时我们观察下内存情况,发现堆内存中一共新建了 3 千多万个 Jet 对象。
  33. 所以,无论是从代码的执行时间(3 毫秒 VS 400 毫秒),还是从堆内存中对象的数量(11 万个 VS 3 千万个)来分析,在上述场景下,开启逃逸分析是有正向益的。
  34. Step 3:测试标量替换
  35. 我们测试下开启和关闭 标量替换,如下图:
  36. 由上图我们可以看出,在上述极端场景下,开启和关闭标量替换对于性能的影响也是满巨大的,另外,同时也验证了标量替换功能生效的前提是逃逸分析已经开启,否则没有意义。
  37. Step 4:测试锁消除
  38. 测试锁消除,我们需要简单调整下代码,即给 allot() 方法中的内容加锁处理,如下:
  39. private static void allot() {
  40. Jet jet = new Jet();
  41. synchronized (jet) {
  42. jet.name = "jet Chen";
  43. }
  44. }
  45. 然后我们运行测试代码,测试结果也很明显,在上述场景下,开启和关闭锁消除对程序性能的影响也是巨大的。
  46. /**
  47. * 进行两种测试
  48. * 关闭逃逸分析,同时调大堆空间,避免堆内GC的发生,如果有GC信息将会被打印出来
  49. * VM运行参数:-Xmx4G -Xms4G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
  50. *
  51. * 开启逃逸分析 jdk8默认开启
  52. * VM运行参数:-Xmx4G -Xms4G -XX:+DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
  53. *
  54. * 执行main方法后
  55. * jps 查看进程
  56. * jmap -histo 进程ID
  57. *
  58. */
  59. @Slf4j
  60. public class EscapeTest {
  61. public static void main(String[] args) {
  62. long start = System.currentTimeMillis();
  63. for (int i = 0; i < 500000; i++) {
  64. alloc();
  65. }
  66. long end = System.currentTimeMillis();
  67. log.info("执行时间:" + (end - start) + " ms");
  68. try {
  69. Thread.sleep(Integer.MAX_VALUE);
  70. } catch (InterruptedException e1) {
  71. e1.printStackTrace();
  72. }
  73. }
  74. /**
  75. * JIT编译时会对代码进行逃逸分析
  76. * 并不是所有对象存放在堆区,有的一部分存在线程栈空间
  77. * Ponit没有逃逸
  78. */
  79. private static String alloc() {
  80. Point point = new Point();
  81. return point.toString();
  82. }
  83. /**
  84. *同步省略(锁消除) JIT编译阶段优化,JIT经过逃逸分析之后发现无线程安全问题,就会做锁消除
  85. */
  86. public void append(String str1, String str2) {
  87. StringBuffer stringBuffer = new StringBuffer();
  88. stringBuffer.append(str1).append(str2);
  89. }
  90. /**
  91. * 标量替换
  92. *
  93. */
  94. private static void test2() {
  95. Point point = new Point(1,2);
  96. System.out.println("point.x="+point.getX()+"; point.y="+point.getY());
  97. // int x=1;
  98. // int y=2;
  99. // System.out.println("point.x="+x+"; point.y="+y);
  100. }
  101. }
  102. @Data
  103. @AllArgsConstructor
  104. @NoArgsConstructor
  105. class Point{
  106. private int x;
  107. private int y;
  108. }

4. Ratio Inlining

Analysis elabi potest statuere certam methodum vocat non effugiet scopo methodi hodiernae. Ideo hae methodi inline possunt optimized ad reducere sumptus methodi vocat et augere exsecutionem progressionis efficientiam.

Per has optimization rationes, analysi evadere possunt auxilium meliorem JVM optimize codicem, purgamentum collectionis supra caput minuere, programma emendare efficientiam et alacritatem exsecutionis, ac memoriam usus minuere.
 

Applicationem missiones

Analysis effugia late patet applicationis missionum in applicationibus actualibus Java.

  1. Cum objectum ut methodus parametri transigitur, analysin effugium potest determinare an objectum evaserit, inde determinans an objectum in acervo vel acervo collocari possit.
    1. Cum objectum adhibetur ut methodus pretii reditus, analysin effugium potest determinare an objectum evaserit, inde determinans an objectum in acervo vel acervo datum sit.
    1. Cum objectum filorum communicatur, analysin effugium potest determinare num obiectum fugit, inde determinans an operationes synchronisationi requirantur.
    1. Cum obiectum temporale in ansa creatur, analysin effugium potest determinare an objectum fugit, inde determinans an objectum saepe creetur et destruatur.

Incommoda effugium analysis

Charta in analysi evadendi anno 1999 edita est, sed usque ad JDK1.6 non impleta est, et haec technologia nondum admodum matura est.

Ratio fundamentalis est quod nulla cautione praestatio consummatio analyseos effugiendi altior erit quam eius consummatio. Etsi analysis effugium facere potest substitutio scalaris, ACERVUS destinatio et clausura eliminatio. Tamen ipsa analysis effugium requirit etiam seriem complexuum analysium, quae actu processum temporis edax est.

Extremum exemplum est quod, post analysim effugiendam, deprehenditur nullum objectum non effugere. Tum processus analyseos effugiendi consumitur.

Etsi haec technologia non admodum matura est, etiam maximum momentum est in technologia technicae aetatis compilator. Animadverti quasdam esse opiniones quae per analysim effugiant, JVM obiectis in acervum non evadet collocant. Hoc est theoretice possibile, sed pendet ex electione JvM excogitatoris. Quantum scio, Oraculum Hotspot JVM hoc non facit. Hoc explicatum est in analysi relata documenta, ut patet omnia exempla objecta in acervo creata esse.

Nunc multi libri versionibus adhuc fundantur antequam JDK7 magnas mutationes subiit. Cache chordarum internarum et variabilium stabilium olim partita est generatio permanentis et generatio permanens ab area metadata est substituta. Attamen chordae chordae internae et variabiles statice ad metadatam aream non transferuntur, sed directe in acervum collocantur, itaque hoc etiam congruit cum conclusione punctum praecedentis: instantiae objecti collocantur in acervo. Exemplum superius obversatur propter scalarem substitutionis.

Beneficia Effugere Analysis


Si objectum intra modum corporis vel intra filum non effugit (vel quod definitum est post analysin effugit non evasit), optimizationes sequentes effici possunt:

Destinatio in ACERVUS:


In communi rerum adiunctis, quae effugere non possunt, magnum spatium relative occupant. Si spatium in acervo adhiberi potest, numerus obiecti destruetur cum methodus desinat, GC pressione reducendo.


Synchroni eliminatio:


Si cincinnus synchronisation est in methodo classis quam definis, sed una tantum stamina in runtime accessura est, codice machina post analysim effugiendam sine cincinno synchronisationi curret.


Substitutio scalare:


Primae datae rationes in Iava virtualis machina (types numerorum ut int, longa, et species referentiarum etc.) ulterius deponi nequeunt, et scalares dici possunt. E contra, si pars data pergere potest dissolvi, aggregatum dicitur. Si analysis effugium probat, obiectum extrinsecus accessum non esse et obiectum esse dissolubile, obiectum non creari potest cum progressio actu exsecuta est, sed potius varias variabiles membri eius hac methodo adhibitas creare directe. Variationes discongregatae possunt separatim enucleari et optimized. Postquam attributa complanata sunt, nihil opus est relationes per regulas notas constituere. Eaedem continenter et arctius condi possunt, quae magis amica est variis schedulis et multum notitiarum tractandorum interdiu servat supplicium. Simul, etiam spatium collocare in ACERVUS frame vel subcriptio respective, ut objectum originale non opus sit totum spatium collocare.

summarium


Iuvenis est locus ubi res nascuntur, augentur et moriuntur. Res hic generatur et ponitur, et tandem colligitur a quisquiliarum collectore et finitur vita sua.

Res cum longae vitae cyclos in antiqua generatione collocari solent, objecta Java ex area superstiti exscripta. Nimirum etiam speciales sunt casus satis longum continuum spatium in nova generatione invenire poterit, JVm ad veterem generationem directe collocabimus. Cum GC solum in iuvenibus generationibus occurrit, actus redivivus iuvenum generationum MinorGc appellatur.

Cum GC in veteri generatione occurrit, vocatur MajorGc vel FullGC. In universum, frequentia MinorGc occursus multo altior quam MajorGC, id est, frequentia purgamentorum collectio in generatione antiqua multo inferior erit quam in generatione novella.

JVM Analysis effugiet duobus modis analysin', static et dynamico, ut determinet an objectum methodi scopo effugiat. Potest auxilium JVM optimize codicem et meliorem efficiendi et memoriae utendi efficientiam programmatum Javae.

Optimization consilia effugiendi analysis includunt in BIBLIOTHECA destinatio, synchronisatio eliminatio, substitutio scalaris, ac methodus inclinatio. Hae optimizationes consilia possunt reducere supra caput purgamentorum collectiones, amplio programmatis exsecutio efficientiam et alacritatem, et memoriam usus minuere.

refer ad:

https://zhuanlan.zhihu.com/p/693382698

JVM-Acervus-Escape Analysis-08-CSDN Blog

JIT memoria effugii analysis_java vertit scalari subrogatio-CSDN Blog

Omnes parametri valores conformatus JVM

java -XX:+PrintFlagsFinal  #输出打印所有参数jvm参数

Insert imaginem descriptionis hic
Insert imaginem descriptionis hic
Insert imaginem descriptionis hic
Insert imaginem descriptionis hic