java字符串池和字符串堆内存分配
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字符串池和字符串堆内存分配的更多相关文章
- Java 字符串常量存放在堆内存还是JAVA方法区?
JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池. JDK1.8开始,取消了Java方法区,取而代之的是位于直接内 ...
- 求你了,别再说Java对象都是在堆内存上分配空间的了!
Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...
- 别再说Java对象都是在堆内存上分配空间的了!
Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...
- JVM知识(一) 求你了,别再说Java对象都是在堆内存上分配空间的了!
求你了,别再说Java对象都是在堆内存上分配空间的了! https://baijiahao.baidu.com/s?id=1661296872935371634&wfr=spider& ...
- 【java虚拟机序列】java中的垃圾回收与内存分配策略
在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...
- 【转载】java项目中经常碰到的内存溢出问题: java.lang.OutOfMemoryError: PermGen space, 堆内存和非堆内存,写的很好,理解很方便
Tomcat Xms Xmx PermSize MaxPermSize 区别 及 java.lang.OutOfMemoryError: PermGen space 解决 解决方案 在 catalin ...
- JAVA 从GC日志分析堆内存 第七节
JAVA 从GC日志分析堆内存 第七节 在上一章中,我们只设置了整个堆的内存大小.但是我们知道,堆又分为了新生代,年老代.他们之间的内存怎么分配呢?新生代又分为Eden和Survivor,他们的比 ...
- Java实例化对象过程中的内存分配
Java实例化对象过程中的内存分配: https://blog.csdn.net/qq_36934826/article/details/82685791 问题引入这里先定义一个很不标准的“书”类,这 ...
- JVM系列(1)- JVM常见参数及堆内存分配
常见参数配置 基于JDK1.6 -XX:+PrintGC 每次触发GC的时候打印相关日志 -XX:+UseSerialGC 串行回收模式 -XX:+PrintGCDetails 打印更详细的GC日志 ...
随机推荐
- spring项目出现无法加载主类
问题:eclipse总是运行之前的项目,新改变的项目内容,不运行.于是我想要是清理缓存,网上说project--->clean指定的项目就可以 但是clean后就无法加载主类了,项目上还出现了红 ...
- 键盘回收(text filed,textview)
键盘回收 #pragma mark - TextField 代理方法 - (BOOL)textFieldShouldReturn:(UITextField *)textField { [self.vi ...
- python之模块2
1.logging模块 等级 debug--->info--->warning(默认)--->error--->critical 配置两种方式: #1.congfig函数 lo ...
- C#_02.13_基础四_.NET方法
C#_02.13_基础四_.NET方法 一.方法概述: 方法是一块具有名称的代码.可以通过方法进行调用而在别的地方执行,也可以把数据传入方法并接受数据输出. 二.方法的结构: 方法头 AND 方法 ...
- 实验楼-Git实战教程
实验1-git介绍 1.版本控制系统: 1)集中式版本控制系统:版本库是集中存放在中央服务器的,工作时需要先从中央服务器取得最新的版本,然后工作完成后把自己的修订推送给中央服务器.这类系统都有一个单一 ...
- poj2376 Cleaning Shifts(区间贪心,理解题意)
https://vjudge.net/problem/POJ-2376 题意理解错了!!真是要仔细看题啊!! 看了poj的discuss才发现,如果前一头牛截止到3,那么下一头牛可以从4开始!!! # ...
- spring中的多线程aop方法拦截
日常开发中,常用spring的aop机制来拦截方法,记点日志.执行结果.方法执行时间啥的,很是方便,比如下面这样:(以spring-boot项目为例) 一.先定义一个Aspect import org ...
- tmux终端工具的简单使用
Linux上管理和运行进程除了程序级别的守护进程之外,经常用到的有比如nohup &的方式,以及screen会话的方式,而Tmux正是一个非常优秀的终端进程管理的软件,和GNU screen类 ...
- 集群安装Java环境
需要安装一个集群环境,发现全部要手动安装java.记录下安装Java环境的过程.虽然,依旧是挨个安装,但总算是有体系了. java 找到下载地址: https://www.oracle.com/tec ...
- 每天一个linux命令(4):mkdir
1.命令简介 mkdir (Make Directory 创建目录): 若指定目录不存在则创建目录.在创建目录时,要求创建目录的用户具有写权限,并应保证新建的目录没有重名. 2.用法 用法:mkdir ...