java 字符常量池
一、题目:
问题:String str = new String(“hello”),“hello”在内存中是怎么分配的? 答案是:堆,字符串常量区。
Java中的字符串常量池和JVM运行时数据区的相关概念。"hello"为字面量对象,其存储在堆内存中。而字符串常量池则存储的是字符串对象的一个引用。
二、Java中的字符串常量池
Java中字符串对象创建有两种形式:
1.字面量形式: 如 String str = "droid";
2.使用new这种标准的构造对象的方法,如 String str = new String("droid");
这两种方式我们在代码编写时都经常使用,尤其是字面量的方式,然而这两种实现其实存在着一些性能和内存占用的差别。这一切都是源于JVM为了减少字符串对象的重复创建。
三、工作原理
当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用,Java能够进行这样的优化是因为字符串是不可变的,可以不用担心数据冲突进行共享。
四、举例说明
package testDemo;
public class test1 {
public static void main(String[] args) {
String st1="hello";
String st2="hello";
System.out.println(st1==st1);
}
}
其结果是:
true

JVM首先检测hello 这个字面量,通过字符串常量池查找不到内容为hello的字符串对象存在,所以创建这个字符串对象,然后将刚创建的对象的引用放入到字符串常量池中,并且将引用返回给变量str1。

同样JVM还是要检测这个字面量,JVM通过查找字符串常量池,发现内容为”hello”字符串对象存在,于是将已经存在的字符串对象的引用返回给变量str2,注意这里不会重新创建新的字符串对象。
使用new创建

当我们使用了new来构造字符串对象的时候,不管字符串常量池中有没有相同内容的对象的引用,新的字符串对象都会创建。
因此我们使用下面代码测试一下

结果返回:flase 表明这两个变量指向的为不同的对象。
使用intern
对于上面使用new创建的字符串对象,如果想将这个对象的引用加入到字符串常量池,可以使用intern方法。 调用intern后,首先检查字符串常量池中是否有该对象的引用,如果存在,则将这个引用返回给变量,否则将引用加入并返回给变量。

输出结果为true
五、疑难问题
前提条件
1.字符串常量池实现的前提条件就是Java中String对象是不可变的,这样可以安全保证多个变量共享同一个对象。如果Java中的String对象可变的话,一个引用操作改变了对象的值,那么其他的变量也会受到影响,显然这样是不合理的。
2.字符串常量池中存放的是引用还是对象,这个问题是最常见的。字符串常量池存放的是对象引用,不是对象。在Java中,对象都创建在堆内存中。
优缺点
优:字符串常量池的好处就是减少相同内容字符串的创建,节省内存空间。
缺:如果硬要说弊端的话,就是牺牲了CPU计算时间来换空间。CPU计算时间主要用于在字符串常量池中查找是否有内容相同对象的引用。不过其内部实现为HashTable,所以计算成本较低。
GC回收
因为字符串常量池中持有了共享的字符串对象的引用,这就是说是不是会导致这些对象无法回收?首先问题中共享的对象一般情况下都比较小。据我查证了解,在早期的版本中确实存在这样的问题,但是随着弱引用的引入,目前这个问题应该没有了
java 字符常量池的更多相关文章
- 触摸java常量池
java常量池是一个经久不衰的话题,也是面试官的最爱,题目花样百出,小菜早就对常量池有所耳闻,这次好好总结一下. 理论 小菜先拙劣的表达一下jvm虚拟内存分布: 程序计数器是jvm执行程序的 ...
- Java 线程池框架核心代码分析--转
原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...
- Java线程池使用说明
Java线程池使用说明 转自:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极 ...
- (转载)JAVA线程池管理
平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...
- Java线程池的那些事
熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但 ...
- Java数据库连接池封装与用法
Java数据库连接池封装与用法 修改于抄袭版本,那货写的有点BUG,两个类,一个用法 ConnectionPool类: package com.vl.sql; import java.sql.Conn ...
- 几个主流java连接池
池(Pool)技术在一定程度上可以明显优化服务器应用程序的性能,提高程序执行效率和降低系统资源开销.这里所说的池是一种广义上的池,比如数据库连接池.线程池.内存池.对象池等.其中,对象池可以看成保存对 ...
- Java连接池详解
于共享资源,有一个很著名的设计模式:资源池(Resource Pool).该模式正是为了解决资源的频繁分配﹑释放所造成的问题.为解决我们的问题,可以采用数据库连接池技术.数据库连接池的基本思想就是为数 ...
- Java数据库连接池
转载过来的,最近在做一个小网站,准备使用这种方法. Java jdbc数据库连接池总结! 1. 引言 近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及, ...
随机推荐
- Java集合之Set
Set也是继承自Collection,Set也是集合的一种,同时Set不允许重复的元素存在.Set的实现类都是基于Map来实现的,其中HashSet是通过HashMap来实现的,TreeSet是通过T ...
- FFMPEG类库打开流媒体的方法(需要传参数的时候)
使用ffmpeg类库进行开发的时候,打开流媒体(或本地文件)的函数是avformat_open_input(). 其中打开网络流的话,前面要加上函数avformat_network_init(). 一 ...
- [转]Maven如何手动添加jar包到本地Maven仓库
Apache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具,由Apache软件基金会所提供.基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项 ...
- PS 滤镜算法原理——照亮边缘
这个算法原理很简单,对彩色图像的R,G,B 三个通道,分别求梯度,然后将梯度值作为三个通道的值. clc; clear all;Image=imread('4.jpg');Image=double(I ...
- HBase BlockCache
1. Cache 读写 调用逻辑: hmaster.handleCreateTable->HRegion.createHRegion-> HRegion. initialize-> ...
- LeetCode(52)-Remove Linked List Elements
题目: Remove all elements from a linked list of integers that have value val. Example Given: 1 --> ...
- LeetCode(31)-Factorial Trailing Zeroes
题目: Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in ...
- 关于java和c++中布尔量的比较
在c++中允许 bool 量和 int 整形常量相互转换,并且用cout<<true; 在控制台上可以输出为 1 int main(int argc, _TCHAR* argv[]) { ...
- C# /VB.NET 创建PDF项目符号列表和多级编号列表
使用项目符号和编号,可以让文档的层次结构更清晰.更有条理,也更容易突出重点.在编辑文档的过程中,我个人也比较偏爱项目标号来标注文章重点信息.在之前的文章中,介绍了如何在Word中来创建项目标号和编号列 ...
- netsh自动配置网络
工作需要经常在多个网络中切换,每次都要配置ip等,写个脚本一键完成配置: netsh interface ip set address "本地连接" static "ip ...