简体   繁体   English

在池和堆中创建字符串

[英]String creation in Pool and Heap

Have few doubts in String, 对String毫无疑问,

I may be wrong with certain statements as i am writing this based on my understanding from various articles on Internet, please bear with me. 根据我在互联网上各种文章中的理解来撰写本文时,某些陈述可能是错误的,请多多包涵。

  1. When we do String str1 = new String ("newStr1"); 当我们做String str1 = new String(“ newStr1”); . This creates 2 string objects. 这将创建2个字符串对象。 One in regular heap and another in string pool. 一个在常规堆中,另一个在字符串池中。 Why 2 objects and their usage? 为什么2个对象及其用法? Why not just one on pool? 为什么不只是一个游泳池?

  2. If we create object as String str2 = new String("newStr2").intern(); 如果我们将对象创建为String str2 = new String(“ newStr2”)。intern(); . This checks if a similar (meaningfully equal) object is there in pool, give a reference to it. 这将检查池中是否存在类似(有意义相等)的对象,并对其进行引用。 If none, it creates one in pool but not in heap? 如果没有,它将在池中创建一个,但不在堆中创建? If so then we should use intern most of the times to save memory? 如果是这样,那么我们应该在大多数时候使用实习生来节省内存吗? Though it would impact performance a bit. 尽管这会稍微影响性能。 So basically it's String str2 = "newStr2"; 所以基本上它是String str2 =“ newStr2”; (interning is implicit for string literals) (对于字符串文字,隐式保留)

  3. After Java-6 the string pool moved from perm gen space to heap area? 在Java-6之后,字符串池已从perm gen空间移至堆区域? So basically we have now just one area as heap or does string pool sits as a separate section in heap now? 因此,基本上,我们现在只有一个区域作为堆,或者字符串池现在作为堆中的一个单独部分放置了吗? If it's not a separate section then still 2 objects are created? 如果不是单独的部分,那么仍然创建2个对象?

Just think the String pool being a special place to store Strings. 只是认为字符串池是存储字符串的特殊位置。 You can consider String pool is also in the heap (it actually is as far as I can tell), just the pool is handled with care that there will be only one copy of each value in it so the same instance can be reused easily (eg when you declare a string literal) 您可以考虑将String池也放置在堆中(实际上据我所知),只是在处理该池时要小心,其中每个值只有一个副本,因此可以轻松地重用同一实例(例如,当您声明字符串文字时)

  1. Because it is told to do so. 因为它被告知要这样做。 "newStr1" is a String literal and it will be created in /looked up from the pool. "newStr1"是一个字符串文字,它将在/从池中查找中创建。 String str1 = new String (...) You are telling JVM to create a new instance of String object. String str1 = new String (...)您正在告诉JVM创建String对象的新实例。 So it is simply following what you tell it to do. 因此,它只是遵循您告诉它要做的事情。 Of course JIT may optimize it to avoid creating new instance (is it doing such kind of optimization now?) but the behavior you described is simply what JVM told to do. 当然,JIT可能会对其进行优化以避免创建新实例(它现在是否在进行这种优化?),但是您描述的行为只是JVM告知要做的事情。

  2. It just worked same as above. 它的工作原理与上述相同。 However, after you new String(...) (which created a new String object), you called intern() and hence do the lookup in String pool. 但是,在您创建了new String(...) (创建了一个新的String对象)之后,您调用了intern()并因此在字符串池中进行了查找。 Again, the behavior is what it is told to do. 同样,该行为就是要执行的操作。 And yes, you are right, in your case the result is just the same as String str1="asdf"; 是的,您是对的,在您的情况下,结果与String str1="asdf"; with some unnecessary work done. 完成一些不必要的工作。 However there are cases that the constructor is not taking a String literal and you still want to enforce the String to be in string pool. 但是,在某些情况下,构造函数没有采用String文字,而您仍然希望将String强制放入字符串池中。 In such case intern() will become meaningful. 在这种情况下, intern()将变得有意义。

  3. Perm Gen IS part of the heap area. Perm Gen IS是堆区域的一部分。 (Sun/Oracle pre-8) JVM divides the heap into different generations and move objects around, which affect how objects are GC-ed . (Sun / Oracle 8之前的版本)JVM将堆分为不同的代,并移动对象,这会影响对象对GC进行编辑的方式。 PermGen is simply the part in heap that never got GC-ed. PermGen只是堆中从未进行过GC编辑的部分。 However, it is still part of heap. 但是,它仍然是堆的一部分。 Therefore, PermGen is more related to GC algorithm and you may notice, there is no PermGen in JDK8 anymore. 因此,PermGen与GC算法更相关,您可能会注意到,JDK8中不再有PermGen。

In java if JVM identifies the literal("xyz") it will immediately create an object in String constant pool and at the same time if it identifies new then it will create an object in heap.now moving forward to queries: 在Java中,如果JVM标识了literal(“ xyz”) ,它将立即在String常量池中创建一个对象,同时,如果它标识了new,则它将在heap.new中创建一个对象。

1.String str1 = new String ("newStr1") ; 1.String str1 = new String(“ newStr1”) ; here for JVM "newStr1" is literal so it will follow rules corresponding to literals,so it creates an object in String constant pool. 对于JVM,“ newStr1”是文字,因此它将遵循与文字对应的规则,因此它将在String常量池中创建一个对象。 new String("newStr1")-- here for new operator it follows the rules corresponding to new operator,so it will create an object in heap as well. new String(“ newStr1”)-在这里,对于new运算符,它遵循与new运算符相对应的规则,因此也会在堆中创建一个对象。

2.intern() :here intern will not create an object in pool.interno is for changing your string object to refer to string pool instead of heap. 2.intern() :这里的intern不会在pool中创建对象.interno用于将字符串对象更改为引用字符串池而不是堆。 string s1 = new String("newStr1") -- here s1 will be pointing to heap area not string constant pool. 字符串s1 = new String(“ newStr1”) -此处s1将指向堆区域而不是字符串常量池。 String s1 = new String("newStr1").intern() will make s1 to point to string constant pool,because newStr1 is created in both heap and string constant pool. 字符串s1 = new String(“ newStr1”)。intern()将使s1指向字符串常量池,因为在堆和字符串常量池中都创建了newStr1 intern() will not deal with string object creation. intern()将不处理字符串对象的创建。

3.permgen : for making effective garbage collection heap is divided into different regions like among that permgen is also a region,still it is inside heap only,it is a region inside heap.please refer this http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/ link for heap regions. 3.permgen:为了使垃圾收集有效,堆被分成不同的区域,例如permgen也是一个区域,它仍然仅位于堆内部,它是堆内部的区域。请参考此http://www.cubrid.org / blog / dev-platform / understanding-java-garbage-collection /堆区域的链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM