<small id='jXZkZ'></small><noframes id='jXZkZ'>

    <tfoot id='jXZkZ'></tfoot>
      <bdo id='jXZkZ'></bdo><ul id='jXZkZ'></ul>
    1. <i id='jXZkZ'><tr id='jXZkZ'><dt id='jXZkZ'><q id='jXZkZ'><span id='jXZkZ'><b id='jXZkZ'><form id='jXZkZ'><ins id='jXZkZ'></ins><ul id='jXZkZ'></ul><sub id='jXZkZ'></sub></form><legend id='jXZkZ'></legend><bdo id='jXZkZ'><pre id='jXZkZ'><center id='jXZkZ'></center></pre></bdo></b><th id='jXZkZ'></th></span></q></dt></tr></i><div id='jXZkZ'><tfoot id='jXZkZ'></tfoot><dl id='jXZkZ'><fieldset id='jXZkZ'></fieldset></dl></div>
      1. <legend id='jXZkZ'><style id='jXZkZ'><dir id='jXZkZ'><q id='jXZkZ'></q></dir></style></legend>

        使用 Java 7 进行逃逸分析/堆栈分配的资格

        Eligibility for escape analysis / stack allocation with Java 7(使用 Java 7 进行逃逸分析/堆栈分配的资格)
          <tbody id='W0Vmy'></tbody>
          <tfoot id='W0Vmy'></tfoot>

                  <bdo id='W0Vmy'></bdo><ul id='W0Vmy'></ul>

                  <legend id='W0Vmy'><style id='W0Vmy'><dir id='W0Vmy'><q id='W0Vmy'></q></dir></style></legend>
                • <small id='W0Vmy'></small><noframes id='W0Vmy'>

                  <i id='W0Vmy'><tr id='W0Vmy'><dt id='W0Vmy'><q id='W0Vmy'><span id='W0Vmy'><b id='W0Vmy'><form id='W0Vmy'><ins id='W0Vmy'></ins><ul id='W0Vmy'></ul><sub id='W0Vmy'></sub></form><legend id='W0Vmy'></legend><bdo id='W0Vmy'><pre id='W0Vmy'><center id='W0Vmy'></center></pre></bdo></b><th id='W0Vmy'></th></span></q></dt></tr></i><div id='W0Vmy'><tfoot id='W0Vmy'></tfoot><dl id='W0Vmy'><fieldset id='W0Vmy'></fieldset></dl></div>
                  本文介绍了使用 Java 7 进行逃逸分析/堆栈分配的资格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在用 转义分析,以便更好地了解哪些对象有资格进行堆栈分配.

                  I am doing some tests with escape analysis in Java 7 in order to better understand what objects are eligible to stack allocation.

                  这是我为测试堆栈分配而编写的代码:

                  Here is the code I wrote to test stack allocation:

                  import java.util.ArrayList;
                  import java.util.Iterator;
                  
                  
                  public class EscapeAnalysis {
                  
                      private static final long TIME_TO_TEST = 10L * 1000L; // 10s
                  
                      static class Timestamp {
                          private long millis;
                          public Timestamp(long millis) {
                              this.millis = millis;
                          }
                          public long getTime() {
                              return millis;
                          }
                          public void setTime(long time) {
                              millis = time;
                          }
                      }
                  
                      public static void main(String[] args) {
                          long r = 0;
                          System.out.println("test1");
                          r += test1();
                          System.out.println("test2");
                          r += test2();
                          System.out.println("test3");
                          r += test3();
                          System.out.println("test4");
                          r += test4();
                          System.out.println("test5");
                          r += test5();
                          System.out.println("test6");
                          r += test6();
                          System.out.println(r);
                      }
                  
                      public static long test1() {
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              r += new Timestamp(System.currentTimeMillis()).getTime();
                          }
                          return r;
                      }
                  
                      public static long test2() {
                          ArrayList<Integer> l = new ArrayList<Integer>(1000);
                          for (int i = 0; i < 1000; ++i) {
                              l.add(i);
                          }
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              for (Iterator<Integer> it = l.iterator(); it.hasNext(); ) {
                                  r += it.next().longValue();
                              }
                          }
                          return r;
                      }
                  
                      public static long test3() {
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              Timestamp ts = new Timestamp(System.currentTimeMillis());
                              ts.setTime(42);
                              r += ts.getTime();
                          }
                          return r;
                      }
                  
                      public static long test4() {
                          ArrayList<Integer> l = new ArrayList<Integer>(1000);
                          for (int i = 0; i < 1000; ++i) {
                              l.add(i);
                          }
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              Iterator<Integer> it = l.iterator();
                              r += it.next().longValue();
                              r += it.next().longValue();
                              r += it.next().longValue();
                              r += it.next().longValue();
                          }
                          return r;
                      }
                  
                      public static long test5() {
                          ArrayList<Integer> l = new ArrayList<Integer>(1000);
                          for (int i = 0; i < 1000; ++i) {
                              l.add(i);
                          }
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              Iterator<Integer> it = l.iterator();
                              for (int i = 0; i < l.size(); ++i) {
                                  r += it.next().longValue();
                              }
                          }
                          return r;
                      }
                  
                      public static long test6() {
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              for (Timestamp ts = new Timestamp(System.currentTimeMillis());
                                      ts.getTime() > 0;
                                      ts.setTime(ts.getTime() + System.currentTimeMillis())) {
                                  r += ts.getTime();
                              }
                          }
                          return r;
                      }
                  
                  }
                  

                  这是它在 Linux 上使用 Java 7 输出的结果

                  And here is what it outputs with Java 7 on Linux

                  java -server -version                                                 
                  java version "1.7.0_02"
                  Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
                  Java HotSpot(TM) 64-Bit Server VM (build 22.0-b10, mixed mode)
                  
                  java -server -verbose:gc -XX:CompileThreshold=1 -cp bin EscapeAnalysis
                  test1
                  test2
                  [GC 15616K->352K(59776K), 0,0014270 secs]
                  [GC 15968K->288K(59776K), 0,0011790 secs]
                  [GC 15904K->288K(59776K), 0,0018170 secs]
                  [GC 15904K->288K(59776K), 0,0011100 secs]
                  [GC 15904K->288K(57152K), 0,0019790 secs]
                  [GC 15520K->320K(56896K), 0,0011670 secs]
                  [GC 15232K->284K(56256K), 0,0011440 secs]
                  test3
                  test4
                  test5
                  [GC 14876K->348K(55936K), 0,0005340 secs]
                  [GC 14620K->348K(56000K), 0,0004560 secs]
                  [GC 14300K->316K(55296K), 0,0004680 secs]
                  [GC 13948K->316K(55488K), 0,0003590 secs]
                  [GC 13692K->316K(54784K), 0,0004580 secs]
                  [GC 13436K->316K(54976K), 0,0005430 secs]
                  [GC 13180K->316K(54272K), 0,0004500 secs]
                  [GC 12924K->316K(54464K), 0,0005090 secs]
                  [GC 12668K->316K(53760K), 0,0004490 secs]
                  [GC 12412K->316K(53888K), 0,0004350 secs]
                  [GC 12156K->316K(53312K), 0,0005060 secs]
                  test6
                  6737499643744733086
                  

                  我正在使用 GC 日志来了解是否在堆栈上分配了对象(想法来自 Escape analysis in Java) 可能不是 100% 可靠,但似乎提供了很好的提示.

                  I am using GC logs to known whether objects were allocated on the stack (idea from Escape analysis in Java) which might not be 100% reliable but seems to give good hints.

                  根据输出,堆栈分配适用于 test1、test3、test4 和 test6,不适用于 test2 和 test5.我不明白为什么这不适用于 for 循环中的迭代器,尽管它可以工作

                  Baed on the output, stack allocation works for test1, test3, test4 and test6 and doesn't work for test2 and test5. I don't understand why this doesn't work with an iterator in for-loop although it works

                  • 在 for 循环外使用迭代器(参见 test4),
                  • 在 for 循环中使用另一个对象(参见 test6).

                  我已阅读 ArrayList 迭代器 我不明白为什么它不能在测试 2 和 5 中进行堆栈分配,因为它既不转义当前方法也不转义当前线程.

                  I have read the code for the ArrayList iterator and I don't understand why it would not be eligible for stack allocation in tests 2 and 5 since it does neither escape the current method nor the current thread.

                  有什么想法吗?

                  推荐答案

                  EA 是 C2 编译器根据它生成的 IR 分析的东西,因此您需要它来编译方法才能享受好处.每个测试只调用一次,因此没有机会编译.热点内部 wiki 中有关 EA 和 C2 IR 的详细信息 (https://wiki.openjdk.java.net/display/HotSpot/Overview+of+Ideal,+C2%27s+high+level+intermediate+representation 和 https://wiki.openjdk.java.net/display/HotSpot/EscapeAnalysis)

                  EA is something the C2 compiler analyses based on the IR it generates therefore you need it to compile the method before enjoying the benefits. Each test is called once only so there is no chance for it to compile. Details on EA and the C2 IR in the hotspot internals wiki (https://wiki.openjdk.java.net/display/HotSpot/Overview+of+Ideal,+C2%27s+high+level+intermediate+representation and https://wiki.openjdk.java.net/display/HotSpot/EscapeAnalysis)

                  这是一个试图展示影响的版本

                  Here's a version that attempts to show the impact

                  import com.sun.management.ThreadMXBean;
                  
                  import java.lang.management.ManagementFactory;
                  import java.util.ArrayList;
                  import java.util.Iterator;
                  
                  
                  public class EscapeAnalysisTest {
                  
                      private static final long TIME_TO_TEST = 10L * 1000L; // 10s
                  
                      static class Timestamp {
                          private long millis;
                  
                          public Timestamp(long millis) {
                              this.millis = millis;
                          }
                  
                          public long getTime() {
                              return millis;
                          }
                  
                          public void setTime(long time) {
                              millis = time;
                          }
                      }
                  
                      public static void main(String[] args) {
                          System.out.println("****");
                          doIt();
                          System.out.println("****");
                          doIt();
                          System.out.println("****");
                          doIt();
                          System.out.println("****");
                          doIt();
                          System.out.println("****");
                      }
                  
                      private static void doIt() {
                          final ThreadMXBean mxbean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
                          final long tid = Thread.currentThread().getId();
                          long r = 0;
                          final long allocPre = mxbean.getThreadAllocatedBytes(tid);
                          r += test1();
                          long alloc1 = mxbean.getThreadAllocatedBytes(tid);
                          System.out.println("test1 - " + (alloc1 - allocPre));
                          r += test2();
                          final long alloc2 = mxbean.getThreadAllocatedBytes(tid);
                          System.out.println("test2 - " + (alloc2 - alloc1));
                          r += test3();
                          final long alloc3 = mxbean.getThreadAllocatedBytes(tid);
                          System.out.println("test3 - " + (alloc3 - alloc2));
                          r += test4();
                          final long alloc4 = mxbean.getThreadAllocatedBytes(tid);
                          System.out.println("test4 - " + (alloc4 - alloc3));
                          r += test5();
                          final long alloc5 = mxbean.getThreadAllocatedBytes(tid);
                          System.out.println("test5 - " + (alloc5 - alloc4));
                          r += test6();
                          final long alloc6 = mxbean.getThreadAllocatedBytes(tid);
                          System.out.println("test6 - " + (alloc6 - alloc5));
                          System.out.println(r);
                      }
                  
                      public static long test1() {
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              r += new Timestamp(System.currentTimeMillis()).getTime();
                          }
                          return r;
                      }
                  
                      public static long test2() {
                          ArrayList<Integer> l = new ArrayList<Integer>(1000);
                          for (int i = 0; i < 1000; ++i) {
                              l.add(i);
                          }
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              for (Iterator<Integer> it = l.iterator(); it.hasNext(); ) {
                                  r += it.next().longValue();
                              }
                          }
                          return r;
                      }
                  
                      public static long test3() {
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              Timestamp ts = new Timestamp(System.currentTimeMillis());
                              ts.setTime(42);
                              r += ts.getTime();
                          }
                          return r;
                      }
                  
                      public static long test4() {
                          ArrayList<Integer> l = new ArrayList<Integer>(1000);
                          for (int i = 0; i < 1000; ++i) {
                              l.add(i);
                          }
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              Iterator<Integer> it = l.iterator();
                              r += it.next().longValue();
                              r += it.next().longValue();
                              r += it.next().longValue();
                              r += it.next().longValue();
                          }
                          return r;
                      }
                  
                      public static long test5() {
                          ArrayList<Integer> l = new ArrayList<Integer>(1000);
                          for (int i = 0; i < 1000; ++i) {
                              l.add(i);
                          }
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              Iterator<Integer> it = l.iterator();
                              for (int i = 0; i < l.size(); ++i) {
                                  r += it.next().longValue();
                              }
                          }
                          return r;
                      }
                  
                      public static long test6() {
                          long r = 0;
                          long start = System.currentTimeMillis();
                          while (System.currentTimeMillis() - start < TIME_TO_TEST) {
                              for (Timestamp ts = new Timestamp(System.currentTi());
                                   ts.getTime() > 0;
                                   ts.setTime(ts.getTime() + System.currentTimeMillis())) {
                                  r += ts.getTime();
                              }
                          }
                          return r;
                      }
                  
                  }
                  

                  使用 -server -XX:CompileThreshold=1 运行时会生成以下输出

                  ****
                  test1 - 109048
                  test2 - 89243416
                  test3 - 16664
                  test4 - 42840
                  test5 - 71982168
                  test6 - 1400
                  -5351026995119026839
                  ****
                  test1 - 16432
                  test2 - 85921464
                  test3 - 16664
                  test4 - 42840
                  test5 - 66777600
                  test6 - 1368
                  7844020592566674506
                  ****
                  test1 - 48
                  test2 - 18256
                  test3 - 272
                  test4 - 18264
                  test5 - 18264
                  test6 - 272
                  -2137858376905291730
                  ****
                  test1 - 48
                  test2 - 18256
                  test3 - 272
                  test4 - 18264
                  test5 - 18264
                  test6 - 272
                  3273987624143297143
                  ****
                  

                  这里的一个危险是这个方法的编译从根本上改变了它,我没有试图防范这种情况,所以使用 LogCompilationPrintCompilation 可能需要检查.

                  one danger here is that the compilation of this method has changed it more fundamentally, I haven't attempted to guard against this so some use of LogCompilation or PrintCompilation might be required to check.

                  这篇关于使用 Java 7 进行逃逸分析/堆栈分配的资格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Maven JAVA_HOME environment variable is not defined correctly, but it is(Maven JAVA_HOME 环境变量未正确定义,但它是)
                  Java System Environment Variable(Java 系统环境变量)
                  Java -classpath option(Java -classpath 选项)
                  Read environment variable in SpringBoot(在 SpringBoot 中读取环境变量)
                  Tomcat 8 - context.xml use Environment Variable in Datasource(Tomcat 8 - context.xml 在数据源中使用环境变量)
                  Issue with JAVA_HOME(JAVA_HOME 的问题)

                      <tbody id='9nvdw'></tbody>
                      <i id='9nvdw'><tr id='9nvdw'><dt id='9nvdw'><q id='9nvdw'><span id='9nvdw'><b id='9nvdw'><form id='9nvdw'><ins id='9nvdw'></ins><ul id='9nvdw'></ul><sub id='9nvdw'></sub></form><legend id='9nvdw'></legend><bdo id='9nvdw'><pre id='9nvdw'><center id='9nvdw'></center></pre></bdo></b><th id='9nvdw'></th></span></q></dt></tr></i><div id='9nvdw'><tfoot id='9nvdw'></tfoot><dl id='9nvdw'><fieldset id='9nvdw'></fieldset></dl></div>
                      1. <tfoot id='9nvdw'></tfoot>
                      2. <legend id='9nvdw'><style id='9nvdw'><dir id='9nvdw'><q id='9nvdw'></q></dir></style></legend>

                        <small id='9nvdw'></small><noframes id='9nvdw'>

                            <bdo id='9nvdw'></bdo><ul id='9nvdw'></ul>