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 ...
随机推荐
- 如何使用 URLOpenStream 函数
URLOpenStream 和 URLDownloadToFile 类似, 都是下载文件的 COM 函数; 前者是下载到 IStream 流, 后者是直接下载到指定路径; 不如后者使用方便. 它们都声 ...
- 不确定行数的多行文本垂直水平居中的css
ul li { position:relative; display: table; width:3rem; height:3rem; background:url('image/defaultBg. ...
- BareTail大文件日志实时查看工具
BareTail 动态的查看日志文件,就像Linux上的tail tail -f nohup.out 功能: 实时文件查看 tail命令模式,自动滚动 支持2g以上大文件 自动滚动 彩色监控 多文件监 ...
- Android App Crash, send email to author
http://www.iriphon.com/2011/06/23/how-do-i-get-android-crash-logs/
- linux环境中安装ftp服务
需求说明: 今天项目中有一个新的需求,需要在linux环境中搭建一个ftp服务,在此记录下. 操作过程: 1.通过yum的方式安装ftp服务对应的软件包 [root@testvm01 ~]# yum ...
- python的初始化运行了哪些?
下面的3个print一个是在模块下面,一个是函数里面,一个是类名下面(不在方法里面) 1. 运行这段代码可以发现第3行和11行可以打印出来.第7行没有打印出来.所以可以放心,函数或者方法里面就算有错误 ...
- SpringMVC------pom.xml添加spring依赖,统一管理版本
如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.or ...
- Linux下tomcat无法启动
场景:干净的tomcat,刚解压 1 通过./startup.sh,提示启动成功,但查看没有日志 2 通过netstat -tln查看端口,发现找不到8080 3 通过./catalina.sh ru ...
- 02-centOS6.7安装
CentOS6.5在VMware10中安装 1.启动VMware的画面 2.点击File--->New Virtual Machine 创建一台新虚拟机 3.在弹出框中选择典型安装 4.选择I ...
- ASP.NET MVC 4 (二)控制器
MVC中控制器负责处理请求,由它操作数据模型,最后返回视图给用户. IController接口 所有的控制器类以Controller结尾,必须实现System.Web.Mvc.IController接 ...