String 如何在visualvm中查看所有字符串对象?

String 如何在visualvm中查看所有字符串对象?,string,java-8,profiling,heap,visualvm,String,Java 8,Profiling,Heap,Visualvm,我尝试学习如何使用java分析器,并选择VisualVM。 此时此刻,我不明白它是如何工作的,因为它可以看到堆中的对象。 例如,我声明了三个对象 public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (!scanner.nextLine().equals("q")) { String s1 = "cat"; String s2

我尝试学习如何使用java分析器,并选择VisualVM。 此时此刻,我不明白它是如何工作的,因为它可以看到堆中的对象。 例如,我声明了三个对象

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    while (!scanner.nextLine().equals("q")) {
        String s1 = "cat";
        String s2 = new String("cat");
        String s3 = new String("cat9");
    }
}

因此,字符串池中有一个“cat”,堆中有一个“cat”和“cat9”作为字符串对象。 但当我在VisualVM中进行堆转储并找到所有带有

select s from java.lang.String s where s.toString().substring(0,3) == "cat"
我只看到两个物体:“猫”和“猫9”。
难道不应该有两个“cat”:一个在字符串池中,另一个在堆中吗?

首先,所有
string
对象都在堆内存中,无论是否被池引用。然后,您将创建四个字符串,两个字符串的内容为“cat”,两个字符串的内容为“cat9”。不过,这并不意味着它们会留在记忆中。由于您没有记录创建堆转储的时间和方式,因此我们对此无话可说。@Holger我更新了相关代码。所以,按照我的计划,所有对象都应该有一个引用(并且在堆中),而我没有输入“q”。堆转储在这里,因此当程序在
nextLine()
中等待时,您将使用堆转储?此时,循环体中声明的变量都不在范围内。但值得注意的是,即使是作用域中的局部变量也不一定会阻止引用对象在未使用时的垃圾收集。