1. String str=new String("abc")和String str="abc"的字符串“abc”都是存放在堆中,而不是存在

栈中。
 2. 其实在在java中有一个“字符数据池”的内存管理机制。
 3. String str="abc",执行这句话时,会先去“字符数据池”搜索时候有“abc”这个字符串,如果有

,则将字符串的首地址赋值给str,如果没有,生成一个新的字符串“abc”并且将首地址赋值给str;
 4. String str=new String("abc"),执行这句话时,不会考虑时候已经存在了“abc”这个字符串,而

是直接生成一个新的字符串“abc”并将首地址赋值给str,注意“abc”并不放在“字符数据池”中;
 5. 由以上分析可知,String str="abc"和效率要高于String str=new String("abc"),因为如果有重复

的字符串时,第一种方式可以节省空间。
 6. 下面举例说明一下,好好看看结果,仔细分析原因,上面已经说明的很清楚了:
public class Test{
 public static void main(String args[]){
  String s1=new String("abc");//直接在堆中生成新的“abc”
  String s2=new String("abc");//直接在堆中生成新的“abc”
  String s3="abc";//先去“字符数据池”搜索时候有“abc”这个字符串,如果有,则

将字符串的首地址赋值给s3,如果没有,则在“字符数据池”中生成一个新的字符串“abc”并且将首地

址赋值给s3;
  String s4="abc";//去“字符数据池”搜索时发现了上一步生成的“abc”这个字符串

,把该字符串首地址赋值给s4,这时其实s3和s4指向同一个字符数据池中的“abc”
  System.out.println(s1==s2);
  System.out.println(s1==s3);
  System.out.println(s2==s3);
  System.out.println(s3==s4);
 }
}

结果:
false
fasle
false
true

另外:例如:

String str1=”java”;    //指向字符串池
String str2=”blog”;   //指向字符串池

String s=str1+str2;   //s是指向堆中值为"javablog"的对象,+运算符会在堆中建立来两个String对象,这两个对象的值分别是"java" "blog". 也就是说从字符串池中复制这两个值,然后在堆中创建两个对象,然后再建立对象s,然后将"javablog"的堆地址赋给s.    这句共创建了?个String 对象!

System.out.println(s==”javablog”);   //结果是false。
Jvm确实对型如String str1=”java”;的String对象放在常量池里,但是它是在编译时那么做的,而String s=str1+str2;是在运行时刻才能知道,也就是说str1+str2是在堆里创建的,所以结果为false了。

如果改成一下两种方式:

String s="java" + "blog"; //直接将"javablog"放入字符串池中,System.out.println(s==”javablog”); 的结果为true, 这个句子创建了?个String对象

String s=str1+ "blog"; //不放入字符串池,而是在堆中分配,System.out.println(s==”javablog”); 的结果为False,    这个句子创建了?个String对象

总结

综上所述,创建字符串有两种方式:两种内存区域(pool,heap)

1," " 引号创建的字符串在字符串池中

2,new,new创建字符串时首先查看池中是否有相同值的字符串,如果有,则拷贝一份到堆中,然后返回堆中的地址;如果池中没有,则在堆中创建一份,然后返回堆中的地址(注意,此时不需要从堆中复制到池中,否则,将使得堆中的字符串永远是池中的子集,导致浪费池的空间)!

另外,对字符串进行赋值时,如果右操作数含有一个或一个以上的字符串引用时,则在堆中再建立一个字符串对象,返回引用;如String s=str1+ "blog";

java字符串池和字符串堆内存分配的更多相关文章

  1. Java 字符串常量存放在堆内存还是JAVA方法区?

    JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池. JDK1.8开始,取消了Java方法区,取而代之的是位于直接内 ...

  2. 求你了,别再说Java对象都是在堆内存上分配空间的了!

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...

  3. 别再说Java对象都是在堆内存上分配空间的了!

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...

  4. JVM知识(一) 求你了,别再说Java对象都是在堆内存上分配空间的了!

    求你了,别再说Java对象都是在堆内存上分配空间的了! https://baijiahao.baidu.com/s?id=1661296872935371634&wfr=spider& ...

  5. 【java虚拟机序列】java中的垃圾回收与内存分配策略

    在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...

  6. 【转载】java项目中经常碰到的内存溢出问题: java.lang.OutOfMemoryError: PermGen space, 堆内存和非堆内存,写的很好,理解很方便

    Tomcat Xms Xmx PermSize MaxPermSize 区别 及 java.lang.OutOfMemoryError: PermGen space 解决 解决方案 在 catalin ...

  7. JAVA 从GC日志分析堆内存 第七节

    JAVA 从GC日志分析堆内存 第七节   在上一章中,我们只设置了整个堆的内存大小.但是我们知道,堆又分为了新生代,年老代.他们之间的内存怎么分配呢?新生代又分为Eden和Survivor,他们的比 ...

  8. Java实例化对象过程中的内存分配

    Java实例化对象过程中的内存分配: https://blog.csdn.net/qq_36934826/article/details/82685791 问题引入这里先定义一个很不标准的“书”类,这 ...

  9. JVM系列(1)- JVM常见参数及堆内存分配

    常见参数配置 基于JDK1.6 -XX:+PrintGC 每次触发GC的时候打印相关日志 -XX:+UseSerialGC 串行回收模式 -XX:+PrintGCDetails 打印更详细的GC日志 ...

随机推荐

  1. java 上传图片 并压缩图片大小(转)

    Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生 ...

  2. YUV422 YUV420 Planar \ Semi-Planar \ Interleaved YCbCr与YUV

    YCbCr是DVD.摄像机.数字电视等消费类视频产品中,常用的色彩编码方案.YCbCr 有时会称为 YCC..Y'CbCr 在模拟分量视频(analog component video)中也常被称为 ...

  3. nvidia-smi命令输出详解

    nvidia-smi命令输出如下: +-----------------------------------------------------------------------------+ | ...

  4. 初识Vulkan【转】

    Vulkan是Khronos组织制定的“下一代”开放的图形显示API.是与DirectX12能够匹敌的GPU API标准. Vulkan是基于AMD的Mantle API演化而来,眼下Vulkan 1 ...

  5. AOP - C# Fody中的方法和属性拦截

    很久很久以前用过postsharp来做AOP, 大家知道的,现在那东东需要付费,于是尝试了一下Fody,但是发现Fody跟新太快了,所以大家在安装fody的时候尽力安装老的版本:packages.co ...

  6. IntelliJ IDEA 下载安装(含注册码)

    https://blog.csdn.net/mashuai720/article/details/79389314

  7. HashSet代码分析

    HashSet (jdk 1.7)的继承关系如下: HashSet是使用HashMap实现的一个没有重复元素的集合.HashSet用法如下: HashSet<String> hashSet ...

  8. docker pureftpd

    pureftpd: image: vimagick/pure-ftpd ports: - "21:21" volumes: - ./data/ftpuser:/home/ftpus ...

  9. alibaba的springcloud孵化器项目

    Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案.此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式 ...

  10. iframe之间操作记录

    1.watch.js (function ($) { $.fn.watch = function (callback) { return this.each(function () { //缓存以前的 ...