您的位置 首页 java

Java String intern():有趣的 Q 和 A

    intern()是 java.lang .String对象中的一个有趣的功能。该intern()函数从应用程序中消除了重复的 字符串 对象,并有可能减少应用程序的整体内存消耗。在这篇文章中,让我们更多地了解这个intern()功能。

    1. 功能如何String intern()运作?
    在 Java 堆内存中,维护了一个字符串对象池。当您在字符串对象上调用intern()函数时, JVM 将检查该字符串对象是否已存在于池中。如果存在,则将相同的对象返回给调用者。如果字符串对象不存在,则将该字符串对象添加到池中,并将新添加的字符串对象返回给调用者。

    通过示例和图片学习总是很容易。让我们来看看下面的代码片段:

    1: String s1 = new String(“yCrash”).intern();

    2: String s2 = new String(“yCrash”).intern();

    Java String intern():有趣的 Q 和 A

    初始启动时的 JVM 堆内存

    您的应用程序创建的所有对象都存储在 JVM 的堆内存中。这个 JVM 堆内存内部有一个字符串实习池。最初启动程序时,JVM 的堆内存将没有字符串对象。

    String s1 = new String(“yCrash”).intern();’ 时的 JVM 堆内存 被执行

    Java String intern():有趣的 Q 和 A
    执行第一条语句时String s1 = new String(“yCrash”).intern();,JVM 会检查yCrash字符串对象是否存在于 intern 字符串池中。由于它不存在,这个yCrash字符串将被添加到 intern 字符串池中,并且这个新创建的字符串对象的引用将返回到s1.

    ‘String s2 = new String(“yCrash”).intern();’ 时的 JVM 堆内存 被执行

    Java String intern():有趣的 Q 和 A
    当执行第二条语句时String s2 = new String(“yCrash”).intern();,JVM 将再次检查yCrash字符串对象是否存在于 intern 字符串池中。这一次,yCrash字符串对象出现在实习生字符串池中,因为它是在执行语句 #1 时添加的。现在,这个旧字符串对象的引用将返回到s2. 两者都s1将s2指向同一个yCrash字符串对象。因此,在语句#2 中创建的重复字符串对象yCrash将被丢弃。

    intern()2. 没有函数的字符串是如何工作的
    1: String s3 = new String(“yCrash”);

    2: String s4 = new String(“yCrash”);

    Java String intern():有趣的 Q 和 A

    ‘String s3 = new String(“yCrash”);’ 时的 JVM 堆内存 被执行

    执行第一条语句时String s3 = new String(“yCrash”);,JVM 会将yCrash字符串对象添加到堆内存中,但不会添加到 intern 字符串池中。
    Java String intern():有趣的 Q 和 A ‘String s4 = new String(“yCrash”);’ 时的 JVM 堆内存 被执行

    当执行第二条语句时String s4 = new String(“yCrash”);,JVM 会yCrash在堆内存中创建一个新的字符串对象。因此将在内存中创建副本。如果您的应用程序创建 n 个对象而不调用,则将在内存中创建 n 个字符串对象。这将导致大量的内存浪费。 yCrashyCrash intern() yCrash

    3. 如何intern()和==工作
    由于s1和s2都指向同一个yCrash字符串对象,当你调用和==之间的操作时s1,s2如下所示,你会得到true结果。

    // true will be printed System.out.println(s1 == s2);

    由于s3ands4指向两个不同的yCrash字符串对象,当您调用 and 之间的操作时,==如下所示,您将得到结果。s3s4false

    // false will be printed System.out.println(s3 == s4);

    intern String4、JVM内存区域池存放在哪个位置
    JVM 内存有以下区域:

    堆区(即年轻代+老代)
    元空间
    其他地区
    了解这些 JVM 内存区域。在 Java 1 到 6 的早期版本中,string internpool 存储在 Perm Generation 中。从 Java 7 开始,String intern池存储在 JVM 的堆内存中。为了证实这一点,我们进行了这个简单的实验。

    5. 好用intern()还是好用-XX:+UseStringDeduplication?
    当您-XX:+UseStringDeduplication在应用程序启动期间传递 JVM 参数时,JVM 将尝试消除重复字符串作为垃圾收集过程的一部分。在垃圾收集过程中,JVM 检查内存中的所有对象。作为此过程的一部分,它会尝试识别其中的重复字符串并尝试消除它们。-XX:+UseStringDeduplication 但是,使用JVM 参数有一定的限制。例如,它仅适用于 G1 GC 算法,并且仅在长寿命字符串对象上消除重复项(了解有关此参数的更多信息)。这是一个尝试使用JVM 参数的主要应用程序的有趣案例研究。-XX:+UseStringDeduplication

    另一方面,该intern()函数可以与任何 GC 算法一起使用,也可以用于短期和长期对象。但是,该intern()功能对应用程序响应时间的影响可能超过-XX:+UseStringDeduplication. 有关更多详细信息,请参阅这篇文章“ Java 字符串实习生:性能影响”。

    6. 函数对性能的影响是intern()什么?
    根据这篇文章,您可能已经了解intern()在字符串对象上调用函数有可能从内存中消除重复字符串,从而降低整体内存利用率。但是,它可能会影响响应时间和 CPU 利用率。要了解使用该intern()函数对性能的影响,请再次参考上一节中链接的帖子“Java 字符串实习生:性能影响”。

文章来源:智云一二三科技

文章标题:Java String intern():有趣的 Q 和 A

文章地址:https://www.zhihuclub.com/197034.shtml

关于作者: 智云科技

热门文章

网站地图