String 对象内存分配策略
这个问题可以说是一个高频的面试题目,以前把这个问题弄懂了,最近突然想到这个问题,一时间竟然没有太好的思路了。所以花些时间整理一下其中的知识点。
一、内存分配策略
我们先来看一个题目(这个问题都快看吐了~),你知道正确的运行结果并给出解释吗。不知道也没关系,我会在下面给出具体的分析。
@Testpublic void test() {String s1 = "abc";String s2 = "abc";String s3 = new String("abc");String s4 = new String("abc");System.out.println(s1 == s2); // trueSystem.out.println(s3 == s4); // falseSystem.out.println(s1 == s3); // false}
String s = ""
与 String s = new String("")
两种方式都可以创建字符串对象,它们有什么不同吗。下面的解释会涉及到 java 虚拟机内存区域 方面的知识,不知道的同学可以先了解一下。
1.1 创建对象的方式
String s = "abc"
方式创建的对象,存储在字符串常量池中,在创建字符串对象之前,会先在常量池中检查是否存在 abc
对象。如果存在,则直接返回常量池中 abc
对象的引用,不存在会创建该对象,并将该对象的引用返回给对象 s
。
以 HotSpot 虚拟机为例,在 jdk1.8 之前,字符串常量池在方法区中,为了减小方法区内存溢出的风险,在 jdk1.8 之后就把字符串常量池转移到 java 堆中了。
String s = new String("abc")
这种方式,实际上 abc
本身就是字符串池中的一个对象,在运行 new String()
时,把字符串常量池中的字符串 abc
复制到堆中,因此该方式不仅会在堆中,还会在常量池中创建 abc
字符串对象。 最后把 java 堆中对象的引用返回给 s
。
1.2 问题分析
通过上面的分析,大家应该对问题结果有一个感性的认识了。
s1
指向字符串常量池中的 abc
对象,s2
也指向字符串常量池中的 abc
对象,因此 s1
与 s2
指向的是同一个对象,故 s1 == s2
返回 true
。
s3
与 s4
分别指向 java 堆中两个不同的对象,因此 s3 == s4
是 false
。
s1
与 s3
分别指向字符串常量池中的对象与 java 堆中的对象,s1 == s3
返回值也是 false
。
二、问题扩展
上面的问题清楚了原理还很好理解,下面还有一个例子,理解起来就不那么容易了。
@Testpublic void test() {String s1 = "abc";String s2 = "a";System.out.println(s1 == ("a" + "bc")); // trueSystem.out.println(s1 == (s2 + "bc")); // false }
2.1 字符串常量重载 "+"
"a" + "bc"
是两个字符串常量的拼接,当一个字符串由多个字符串常量连接而成时,它自己也肯定是字符串常量。java 虚拟机对于字符串常量的 “+” 号连接,在程序编译期,java 虚拟机就将常量字符串的 “+” 连接优化为连接后的值。
这样一来,最终只会在常量池中创建一个 abc
对象,并没有创建临时字符串对象 a
和 bc
,减轻了垃圾收集器的压力。s1 == ("a" + "bc")
,因为 abc
(s1
) 在字符串常量池中已经存在了,因此返回值是 true
。
2.2 字符串引用重载 "+"
java 虚拟机对于有字符串引用存在的字符串连接,即 s2 + "bc"
在被编译器执行的时候,会自动引入 StringBuilder
对象,调用其 append()
方法,最终调用 toString()
方法返回其在堆中对象的引用。 下面是反编译后的部分字节码。
因此 s2 + "bc"
就等同于下面过程。
s2 + "bc" = new StringBuilder().append(s2).append("bc").toString();
s1 == (s2 + "bc")
在进行比较时,s1
是字符串常量池中对象的引用,(s2 + "bc")
则是 java 堆中一个对象的引用,因此返回值是 false
。为什么说 s2 + "bc"
返回的是堆中对象的引用呢,只要到 StringBuilder
源码中查看一下 toString()
就能理解了。
/*** StringBuilder 类的 toSTring() 方法*/@Overridepublic String toString() {// Create a copy, don't share the arrayreturn new String(value, 0, count);}
三、参考资料
- String 对象内存分配 (常量池和堆的分配)
- Java—String 字符串运算符"+"重载分析
String 对象内存分配策略相关推荐
- java内存模型 创建类_JVM内存模型及String对象内存分配
昨天看了一篇关于<Java后端程序员1年工作经验总结>的文章,其中有一段关于String和StringBuffer的描述,对于执行结果仍然把握不准,趁此机会也总结了下JVM内存模型. 1. ...
- JVM学习笔记之-堆,年轻代与老年代,对象分配过程,Minor GC、Major GC、Full GC,堆内存大小与OOM,堆空间分代,内存分配策略,对象分配内存,小结堆空间,逃逸分析,常用调优工具
堆的核心概述 概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域.Java堆区在JVM 启动的时候即被创建,其空间大小也就确定了.是JVM管理的最大一块内存空间. 堆内存的大小是可 ...
- 《深入理解Java虚拟机》-----第3章 垃圾收集器与内存分配策略
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来. 3.1 概述 说起垃圾收集(Garbage Collection,G ...
- 垃圾收集器与内存分配策略(五)之垃圾日志与常见参数
2019独角兽企业重金招聘Python工程师标准>>> 垃圾收集器与内存分配策略(五)--垃圾日志与常见参数 理解GC日志 每个收集器的日志格式都可以不一样,但各个每个收集器的日志都 ...
- jvm(3)-垃圾收集器与内存分配策略
[0]README 0.1)本文部分文字转自:深入理解jvm,旨在学习 垃圾收集器与内存分配策略 的基础知识: [1]垃圾回收概述 1)GC(Garbage Collection)需要完成的3件事情: ...
- JVM内存管理:深入垃圾收集器与内存分配策略
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
- java_opts gc回收器_jvm垃圾收集器与内存分配策略
垃圾收集器与内存分配策略: 以下参考周志明的<>. 判断对象是否存活: 引用计数:通过判断对象被引用的次数(为0,则表示不可被使用),但这很难解决对象相互循环引用的问题. 根搜索算法:即采 ...
- 【转】JVM内存管理:深入垃圾收集器与内存分配策略
2019独角兽企业重金招聘Python工程师标准>>> Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收 ...
- jvm垃圾收集器与内存分配策略
2019独角兽企业重金招聘Python工程师标准>>> 垃圾收集器与内存分配策略: 以下参考周志明的<<深入理解jvm高级特性与最佳实践>>. 判断对象是否存 ...
最新文章
- 密码生成常见的编码规则
- C# 拖放操作源码详解2
- python pynlpir中科院分词的使用
- Chuck Cobb谈敏捷组织中PMO的角色
- 如何离线安装chrome插件
- 商务英语计算机,BEC商务英语
- 图的简单应用(C/C++实现)
- 亚马逊首席科学家:揭秘 Alexa 语音识别技术|AI NEXT
- 算法竞赛入门经典训练指南
- GridView的多表头(排序)实例方法
- cpt怎么转换成HTML,Excel直接转成模板cpt
- 盘口功夫——研判股价启动前的四种征兆----
- DAC0832的多功能信号/波形发生器Proteus仿真设计,4种波形(正弦、三角、方波、锯齿),附仿真+C程序+论文等
- 删除右键菜单中的 “上传到wps云文档”
- 探寻埋藏在心底的梦想,社科院与杜兰大学金融管理硕士项目伴你同行
- 点击扫一扫二维码返回文本内容
- 概率论笔记3.1二维随机变量及其函数分布
- 微服务拆分策略和原则
- 如何查询期刊的中科院分区
- java 一个线程占多少内存_一个jvm线程占用多少操作系统内存
热门文章
- Error creating bean with name ‘org.springframework.security.oauth2.config.annotation.web.configurati
- 设计模式——装饰者(Decorator)模式DEMO——成绩汇报的装饰者模式实现
- Python——OpenCV(opencv-python库)调用摄像头
- HMTL/CSS——下拉菜单DEMO
- Nearest Interesting Number
- Maximal Continuous Rest
- Superhero Transformation
- Hive 0.12.0安装配置
- Python基础day08 作业解析【7道 面向对象题目】
- 关于Android 中 一个错误的解决办法 “Do not request Window.FEATURE_ACTION_BAR.....