我正在学习有关Java性能管理的类(class),但是遇到一个问题,该问题使我无法为字符串池打印信息。这是我尝试向池中添加一千万个 String
对象时得到的结果:
E:\IntelliJ Projects\ExploringStrings\src>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
这是使用空主要方法运行程序时得到的结果:E:\IntelliJ Projects\ExploringStrings\src>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万个对象时,为什么不能打印出有关字符串池的信息,而我的教练却可以呢?我无法理解其原因,因为这远远超出了我的Java编程水平。谢谢你们。
最佳答案
tl; dr
请在退出前等待几秒钟,以免出现“此时不可用的统计信息”问题。
Thread.sleep( Duration.ofSeconds( 5 ).toMillis() )
细节如果您在控制台上引用该消息:
statistics unavailable at this moment
…我在使用与您的代码相似的代码时也遇到了同样的情况。
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() ) );
}
}
在AdoptOpenJDK上的具有Java 15的Intel上的macOS Mojave上运行时,在IntelliJ 2020.3.1中执行。/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
等的文档。如果有人有链接,请发表。
关于java - 尝试打印字符串池信息时"statistics unavailable at this time"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65556454/