Java虚拟机九 java.lang.String在虚拟机中的实现
在Java中,Java的设计者对String对象进行了大量的优化,主要有三个特点:
1.不变性:
不变性是指String对象一旦生成,则不能再对它进行改变。String的这个特点可以泛化成不变(immutable)模式,一个对象的状态在对象被创建之后就不再发生变化。不变模式的主要作用在于,当一个对象需要被多线程共享,并且访问频繁时,可以省略同步和锁等待的时间,从而大幅提升系统性能。
不变性可以提高多线程访问的性能。因为对象不可变,因此对于所有线程都是只读的,多线程访问时,即使不加同步也不会产生数据的不一致,故减少了系统的开销。
由于不变性,一些看起来像是修改的操作,实际上都是依靠产生新的字符串实现的。比如 String.substring(),String.concat()方法,他们都没有修改原始字符串,而是产生了一个新的字符串。
如果需要一个可以修改的字符串,那么需要使用StringBuffer或者StringBuilder对象。
2.针对常量池的优化
针对常量池的优化指当两个String对象拥有相同的值时,他们只引用常量池中的同一个拷贝。当同一个字符串反复出现时,这个技术可以大幅节省内存空间。
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1==str2);//false
System.out.println(str1==str2.intern());//false
System.out.println("abc"==str2.intern());//true
System.out.println(str1.intern()==str2.intern());//true
以上代码str1和str2都开辟了一块堆空间存放String实例。虽然str1和str2内容相同,但是在堆空间中的引用是不同的。String.intern()返回字符串在常量池中的引用,显然它和str1也是不相同的,String.intern()始终和常量字符串相等。

3.类的final定义
final类型定义也是String对象的重要特点。作为final类的String对象在系统中不可能有任何子类,这是对系统安全性的保护。
有关String的内存泄漏
内存泄漏就是程序未能释放已经不再使用的内存的情况,他并不是说物理内存消失了,而是指由于不再使用的对象占据内存不被释放,而导致可用内存不断减小,最终有可能导致内存溢出。
以String.substring()方法为例,说明内存泄漏问题:
java.lang.String主要由3部分组成:代表字符数组的value、偏移量offset和长度count.这个结构为内存泄漏埋下伏笔,字符串的实际内容有value,offset,count三者共同决定,而非value一项。如果字符串value数组包含100个字符,而count长度只有1个字节,那么这个String实际上只要1个字符,却占据了至少100个字节,那剩余的99个就属于泄漏的部分,他们不会被使用,不会被释放,却长期占用内存,直到字符串本身被回收。
这种情况在JDK1.6中非常容易出现。String.substring()中,新生成的String并没有从value中获取自己需要的那部分,而是简单的使用了相同的value引用,只是修改了offset和count,以此类确定新的String对象的值。当原始字符串没有被回收时,这种情况是没有问题的,并且通过共用value,还可以节省一部分内存,但是一旦原始字符串被回收,value中多余的部分就造成了空间浪费。
综上所述,如果使用了String.substing()将一个大字符串切割为小字符串,当大字符串被回收时,小字符串的存在就会引起内存泄漏。
在JDK1.7中,去掉了offset和count两项,而String的实质性内容仅由value决定,而value数组本身就代表了这个String实际的取值。
Java虚拟机九 java.lang.String在虚拟机中的实现的更多相关文章
- java学习(九) —— java中的File文件操作及IO流概述
前言 流是干什么的:为了永久性的保存数据. IO流用来处理设备之间的数据传输(上传和下载文件) java对数据的操作是通过流的方式. java用于操作流的对象都在IO包中. java IO系统的学习, ...
- 《深入理解Java虚拟机》Java内存区域与内存溢出异常
注:“蓝色加粗字体”为书本原语 先来一张JVM运行时数据区域图,再接下来一一分析各区域功能: 程序计数器 程序计数器(program Counter Register)是一块较小的内存空间,它可以 ...
- JDK1.8源码(三)——java.lang.String 类
String 类也是java.lang 包下的一个类,算是日常编码中最常用的一个类了,那么本篇博客就来详细的介绍 String 类. 1.String 类的定义 public final class ...
- JAVA虚拟机体系结构JAVA虚拟机的生命周期
一个运行时的Java虚拟机实例的天职是:负责运行一个java程序.当启动一个Java程序时,一个虚拟机实例也就诞生了.当该程序关闭退出,这个虚拟机实例也就随之消亡.如果同一台计算机上同时运行三个Jav ...
- JDK源码-java.lang.String
1.开篇明志 本文来看看String的源码. 2.Java7 API String介绍 String 类代表字符串.Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现. 字符串 ...
- 《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?
Java虚拟机是如何加载Java类的? 这个问题也就是面试常问到的Java类加载机制.在年初面试百战之后,菜鸟喜鹊也是能把这流程倒背如流啊!但是,也只是字面上的背诵,根本就是像上学时背书考试一样. ...
- Java虚拟机栈(java stack)
虚拟机栈(java stack) 百度图片搜索里的动图搜索功能不错,可以搜索一些动图,展示操作数栈的操作过程,比较形象.这点google差点意思 虚拟机栈(jvm stacks)是线程独占的 里面是多 ...
- 【Java】实战Java虚拟机之五“开启JIT编译”
今天开始实战Java虚拟机之五“开启JIT编译” 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实战Ja ...
- 深入理解java虚拟机【Java内存结构】
Java虚拟机规范规定的java虚拟机内存其实就是java虚拟机运行时数据区,其架构如下: 其中方法区和堆是由所有线程共享的数据区. Java虚拟机栈,本地方法栈和程序计数器是线程隔离的数据区. (1 ...
随机推荐
- Global.asax的Application_BeginRequest实现url重写无后缀的代码
本文为大家详细介绍下利用Global.asax的Application_BeginRequest 实现url重写其无后缀,具体核心代码如下,有需求的朋友可以参考下,希望对大家有所帮助 利用Global ...
- struts2危险漏洞解决方法
原创,bgy编写.2013-07-24 前文: 随着苹果开发者网站的沦陷,已经曝光一周的Apache Struts2漏洞再次成为热门话题,今天有消息称由于该漏洞被利用,淘宝的数据库已经被盗,尽管淘宝官 ...
- scala中Map和Set
scala中Set包含可变set和不可变Set,set的子类HashSet,各有一个扩展了可变和不可变的set特质. 可变set import scala.collection.mutable.Se ...
- Nginx服务器之负载均衡策略
http://www.cnblogs.com/1214804270hacker/p/9325150.html
- [Module] 08 - MVP by Mosby
From: Mosby MVP使用教程[作者用心] View是消极视图(Passive View), 它尽量不去主动做事, 让Presenter通过抽象方式控制View 例子: 例如Presenter ...
- ios开发之--令UITableView滚动到指定位置
这个应用场景还是挺多的,代码如下: //获取到需要跳转位置的行数 NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow: inSect ...
- LR 测试http协议xml格式数据接口
Action() { lr_start_transaction("T1"); web_custom_request("xxxxHTTPRequest", &qu ...
- 绕过D盾的一句话
一个很简单的一个技巧,作个笔记,可以绕过D盾检测. 新建test1.php <?php eval($_POST[g]); ?> 新建test2.php <?php $a=" ...
- selenium之 chromedriver与chrome版本映射表(更新至v2.31)
转自:http://blog.csdn.net/huilan_same/article/details/51896672 chromedriver版本 支持的Chrome版本 v2.31 v58-60 ...
- 使用session防止表单进行重复提交
我们都知道可以通过js的方法来实现防止表单重复提交,但是js只适用于“在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交” 的情况下进行操作, 那如果碰到“表单提交后用户点击[刷新 ...