尝试打印字符串池信息时“此时无法统计”?

我正在学习有关 Java 性能管理的 udemy 课程,但遇到了一个问题,该问题阻止我打印出字符串池的信息。这是我尝试向池中添加一千万个 String对象时得到的结果:

E:IntelliJ ProjectsExploringStringssrc>java -XX:+PrintStringTableStatistics Main
Elapsed time was 28311 ms.
SymbolTable statistics:
Number of buckets       :     20011 =    160088 bytes, each 8
Number of entries       :     20527 =    492648 bytes, each 24
Number of literals      :     20527 =    776904 bytes, avg  37.848
Total footprint         :           =   1429640 bytes
Average bucket size     :     1.026
Variance of bucket size :     1.033
Std. dev. of bucket size:     1.017
Maximum bucket size     :         9
statistics unavailable at this moment

这是我使用空的main 方法运行程序时得到的结果:

E:IntelliJ ProjectsExploringStringssrc>java -XX:+PrintStringTableStatistics Main
SymbolTable statistics:
Number of buckets       :     20011 =    160088 bytes, each 8
Number of entries       :     16615 =    398760 bytes, each 24
Number of literals      :     16615 =    608976 bytes, avg  36.652
Total footprint         :           =   1167824 bytes
Average bucket size     :     0.830
Variance of bucket size :     0.837
Std. dev. of bucket size:     0.915
Maximum bucket size     :         9
StringTable statistics:
Number of buckets       :     65536 =    524288 bytes, each 8
Number of entries       :      1734 =     27744 bytes, each 16
Number of literals      :      1734 =    112456 bytes, avg  64.854
Total footprsize_t         :           =    664488 bytes
Average bucket size     :     0.026
Variance of bucket size :     0.027
Std. dev. of bucket size:     0.163
Maximum bucket size     :         2

这是尝试向池中添加 1000 万个字符串的代码:

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        Date start = new Date();

        List<String> strings = new ArrayList<String>();

        for(Integer i = 1; i < 10000000; i++) {
            String s =  i.toString().intern(); //Adds new string object to the string pool
            strings.add(s);
        }

        Date end = new Date();
        System.out.println("Elapsed time was " + (end.getTime() - start.getTime()) + " ms.");

    }
}

所以,我的问题是:当我尝试添加 1000 万个对象时,为什么我不能打印出 String 池的信息,但我的导师可以?我无法理解其中的原因,因为这超出了我的 Java 编程水平。谢谢你们。

回答

tl;博士

退出前等待几秒钟,以避免“此时无法统计”问题。

Thread.sleep( Duration.ofSeconds( 5 ).toMillis() )

细节

如果您指的是控制台上的该消息:

暂时无法统计

……我用和你类似的代码也经历过同样的事情。

package work.basil.example;

import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

public class Stringer
{
    public static void main ( String[] args )
    {
        Instant start = Instant.now();
        System.out.println( "Starting run at:" + start + ". Runtime.version(): " + Runtime.version() );
        List < String > strings = new ArrayList < String >();

        for ( int i = 1 ; i < 10_000_000 ; i++ )
        {
            String s = String.valueOf( i ).intern();  // Adds new string object to the string pool.
            strings.add( s );
        }

        System.out.println( "Elapsed time was " + Duration.between( start , Instant.now() ) );
    }
}

在 IntelliJ 2020.3.1 中使用来自 AdaptOpenJDK 的 Java 15 在 Intel 上的 macOS Mojave 上运行时。

/Library/Java/JavaVirtualMachines/adoptopenjdk-15.jdk/Contents/Home/bin/java -XX:+PrintStringTableStatistics --enable-preview -javaagent:/Users/basilbourque/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/203.6682.168/IntelliJ IDEA 2020.3 EAP.app/Contents/lib/idea_rt.jar=52178:/Users/basilbourque/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/203.6682.168/IntelliJ IDEA 2020.3 EAP.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/basilbourque/IdeaProjects/ExampleJava/target/classes:/Users/basilbourque/.m2/repository/com/h2database/h2/1.4.200/h2-1.4.200.jar:/Users/basilbourque/.m2/repository/com/thedeanda/lorem/2.1/lorem-2.1.jar:/Users/basilbourque/.m2/repository/org/postgresql/postgresql/42.2.18/postgresql-42.2.18.jar:/Users/basilbourque/.m2/repository/org/checkerframework/checker-qual/3.5.0/checker-qual-3.5.0.jar:/Users/basilbourque/.m2/repository/org/apache/commons/commons-csv/1.8/commons-csv-1.8.jar work.basil.example.Stringer
Starting run at:2021-01-04T02:03:34.484633Z. Runtime.version(): 15.0.1+9
Elapsed time was PT6.219106S
SymbolTable statistics:
Number of buckets       :     32768 =    262144 bytes, each 8
Number of entries       :      2633 =     42128 bytes, each 16
Number of literals      :      2633 =     98200 bytes, avg  37.000
Total footprint         :           =    402472 bytes
Average bucket size     :     0.080
Variance of bucket size :     0.079
Std. dev. of bucket size:     0.280
Maximum bucket size     :         2
statistics unavailable at this moment

Process finished with exit code 0

......我得到了目前无法获得的相同统计信息。

因此,根据疯狂的猜测,我Thread.sleep在退出前添加了一个等待 5 秒的调用。

try { Thread.sleep( Duration.ofSeconds( 5 ).toMillis() ); } catch ( InterruptedException e ) { e.printStackTrace(); }

所以,在运行这个:

package work.basil.example;

import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

public class Stringer
{
    public static void main ( String[] args )
    {
        Instant start = Instant.now();
        System.out.println( "Starting run at:" + start + ". Runtime.version(): " + Runtime.version() );
        List < String > strings = new ArrayList < String >();

        for ( int i = 1 ; i < 10_000_000 ; i++ )
        {
            String s = String.valueOf( i ).intern();  // Adds new string object to the string pool.
            strings.add( s );
        }

        System.out.println( "Elapsed time was " + Duration.between( start , Instant.now() ) );
        try { Thread.sleep( Duration.ofSeconds( 5 ).toMillis() ); } catch ( InterruptedException e ) { e.printStackTrace(); }
    }
}

我明白了:

/Library/Java/JavaVirtualMachines/adoptopenjdk-15.jdk/Contents/Home/bin/java -XX:+PrintStringTableStatistics --enable-preview -javaagent:/Users/basilbourque/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/203.6682.168/IntelliJ IDEA 2020.3 EAP.app/Contents/lib/idea_rt.jar=52114:/Users/basilbourque/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/203.6682.168/IntelliJ IDEA 2020.3 EAP.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/basilbourque/IdeaProjects/ExampleJava/target/classes:/Users/basilbourque/.m2/repository/com/h2database/h2/1.4.200/h2-1.4.200.jar:/Users/basilbourque/.m2/repository/com/thedeanda/lorem/2.1/lorem-2.1.jar:/Users/basilbourque/.m2/repository/org/postgresql/postgresql/42.2.18/postgresql-42.2.18.jar:/Users/basilbourque/.m2/repository/org/checkerframework/checker-qual/3.5.0/checker-qual-3.5.0.jar:/Users/basilbourque/.m2/repository/org/apache/commons/commons-csv/1.8/commons-csv-1.8.jar work.basil.example.Stringer
Starting run at:2021-01-04T02:02:21.792377Z. Runtime.version(): 15.0.1+9
Elapsed time was PT5.887848S
SymbolTable statistics:
Number of buckets       :     32768 =    262144 bytes, each 8
Number of entries       :      2635 =     42160 bytes, each 16
Number of literals      :      2635 =     98280 bytes, avg  37.000
Total footprint         :           =    402584 bytes
Average bucket size     :     0.080
Variance of bucket size :     0.079
Std. dev. of bucket size:     0.281
Maximum bucket size     :         2
StringTable statistics:
Number of buckets       :   8388608 =  67108864 bytes, each 8
Number of entries       :  10000880 = 160014080 bytes, each 16
Number of literals      :  10000880 = 480062480 bytes, avg  48.000
Total footprint         :           = 707185424 bytes
Average bucket size     :     1.192
Variance of bucket size :     1.383
Std. dev. of bucket size:     1.176
Maximum bucket size     :         9

Process finished with exit code 0

等待退出后,statistics unavailable at this moment消息消失了,我们得到了完整的统计信息。

我们确实看到Number of literals从几千人跃升至超过一千万人。大概这是由于我们将一千万个数字变成了字符串的循环。

文档?

我试图对此进行研究,以了解PrintStringTableStatistics开关的记录行为。但我找不到任何文件。我不知道现在在哪里可以找到控制台工具java、 等的文档javac

谁有链接,请发一下。


以上是尝试打印字符串池信息时“此时无法统计”?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>