本文介绍了新的字符串对象创建-在普通内存和字符串常量池中分配内存?两个都?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

String s = new String("abc");

当我们使用new关键字时,Java将在普通(非池)内存中创建一个新的String对象,而s将引用它.另外,文字"abc"将放置在池中.

When we use the new keyword, Java will create a new String object in normal(nonpool) memory and s will refer to it. In addition, the literal "abc" will be placed in the pool.

我在认证书中找到了此信息.我对此感到很好奇,JVM在普通内存中添加了"abc"之后在字符串常量池中添加了"abc",那么为什么要在普通内存中创建"abc"呢?而它可以直接在String Constant Pool中分配空间?

I found this information in certification book. I am curious about this, JVM is adding "abc" in String Constant Pool after adding "abc" in normal memory, then why is it creating "abc" in normal memory? Whereas, It can directly allocate space in String Constant Pool?

背后的某些原因?

推荐答案

没有普通内存"和池内存"之类的东西.

There is no such thing as a "normal memory" and "pool memory".

所有String实例都生活在堆上,根据定义,该堆是容纳所有Java对象的内存.有一个字符串池,它基本上是一种哈希映射,其中包含对实例的引用.不需要String实例位于特殊的内存区域中,以供字符串池引用.向池中添加字符串并不意味着任何内存移动.

All String instances live on the heap, which is, by definition, the memory holding all Java objects. There is a string pool, which is basically a kind of hash map, containing references to instances. There is no requirement for the String instance to be in a special memory region, to be referable by the string pool. Adding a string to the pool does not imply any memory movement.

在较早的JVM中,为字符串 literals 创建的实例被放置在一个特殊的内存区域中,以降低被垃圾收集的可能性.由于称为永久生成的内存区域存在一些缺点,因此在Java 8中放弃了该策略并删除了内存区域.这种古老的行为可能会造成一些混乱.但这并不需要池引用的字符串位于该内存区域.

In older JVMs, the instances created for string literals were placed into a special memory region, to accommodate the lower likelihood of being garbage collected. Since that memory region, called permanent generation had some drawbacks, this policy was abandoned and the memory region removed in Java 8. This old behavior might have created some confusion. But it never was a requirement for strings referred by the pool, to be in that memory region.

此外,还不清楚您的问题针对的是什么.您已经编写了代码,请求Java创建两个不同的String实例,而Java将这样做.之所以这样做,是因为您是这样告诉我们的.

Besides that, it’s not clear where your question is aiming at. You have written code requesting Java to create two distinct String instances and Java will do so. The reason why it does so, is, because you told it so.

如果您真的想深入了解技术细节,这就是您的代码将要发生的事情:

If you really want to go deeper into the technical details, this is, what will happen with your code:

  • 首先,为您的new String(…)请求创建一个未初始化的String实例
  • 然后,为您的"abc"文字创建一个String实例并将其添加到池中(除非池中已经包含该内容的字符串)
  • 最后,调用第一步创建的String实例的构造函数,并将第二步的String实例作为参数
    • 在构造函数中,将复制对char[]数组的引用
    • First, an uninitialized String instance is created for your new String(…) request
    • Then, a String instance for your "abc" literal is created and added to the pool (unless the pool does already contain a string of that content)
    • Last, the constructor for the String instance created by the first step is invoked, with the String instance of the second step as argument
      • within the constructor, the reference to the char[] array will be copied

      最后,您有两个实例,它们具有相同的内容,并且都指向同一个数组(自Java 7u6起),因此您所请求的内容均相同,因此,单个数组显然不能位于两个字符串的不同内存区域中.

      At the end, you have two instances with the same contents, as you requested, both pointing to the same array (since Java 7u6), so the single array obviously can’t be in different memory regions for the two strings.

      这篇关于新的字符串对象创建-在普通内存和字符串常量池中分配内存?两个都?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 17:32