- 浏览: 249649 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
探索者_技术:
不错 讲解的比较详细
Java 执行过程详解 - JVM 生命周期 -
besterzhao:
学习了
关于 sun.misc.Unsafe -
lliiqiang:
属性变量被设定为不可更改的,外界传递的对象复制一份再保存到对象 ...
不可变类(immutable class) -
xunke515:
有启发.感谢
Java System 类详解 - in, out, err -
bo_hai:
你说没错。问题是:怎么样把ClassA中的事务传播到Class ...
Spring 事务在多线程环境下的传播
为了性能和内存资源上的考虑,JVM对String类型的数据做了特殊的处理。也就是大家都知道的String是immutable的或者是constant。其实很多面试或者笔试里面都会考到。有时觉得没事找事,确实,对于一般的系统,不需要考虑到底创建了几个string,只管用就是,似乎JVM会处理,至少会GC他们的。其实不然。对于大型项目,或者运行很长时间的项目,或者使用到大量字符串的项目来说,String的开销就不得不考虑。
1. String Literal Constant Pool
literal,就是字符串,数字等值本身。当你在编码的时候写下一个值的时候,比如10,或者“abc”你就写了一个literal。
JVM 维护了一个String Literal Pool,用来存储String Literal。
字符串字是一个由双引号括起来的字符序列。它是指向一个String实例的引用。
比如 String s = “abc”。对于“abc”,它首先是一个String literal,它在创建之后,立即利用String的intern方法,装入到了Literal Pool并返回这个String 实例的引用给s。当你再次写abc”的时候,intern方法会先查看是否已有这个literal了,就会直接返回这个literal对应的String实例的引用。也就是说你循环1000变,内存里面也只有这么一个String literal以及他对应的String的实例。String,本质上是一个Java 类,它的实例除了包含value,也就是这个字符序列外,还有其他的属性和方法。这样看来String Object和Literal本质上是不同的。
其实除了String Literal,还有其他类型的Literal:
只是,只有String Literal有这么一个pool,用来提高性能和节约内存。提高性能,是因为你可以重用已经有的String Object,这样也就节约了内存。
再来看看 new String("abc"), 只有用了双引号,就会涉及到string literal,它的逻辑就是先查看是否已有这个literal,有就返回它的string object 引用,没有就创建一个,并生成一个string的object,然后把这个object的引用返回。可见,没有string literal有且仅有一个string object与之对应。回到这句话,new String("abc"),只有用到new,就会新建一个object,这里是新建一个string object。这就都明白了吧。看一个例子:
输出 true。也就是只生成了一个对象。
2. 编译时计算和运行时计算的区别
看下面:
输出:false true。上面的程序,"abc" + "abc"是常量运算表达式constant expression。编译器就可以计算出值了,这就是编译时计算。同时这个表达式会被看做是string literal。但是:String s3 = s1+s2;那么s3的值就只能在运行的时候才能确定,这就是运行时计算。可见运行时会创建一个新的String,并且不会被当成string literal。
3. Intern
下面是String的intern方法的注释和签名,可见是一个native方法。
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
All literal strings and string-valued constant expressions are interned.
public native String intern();
String提供了方法Intern让我们把显示的调用来把String对象放入到literal pool里面并返回这个新的引用。
输出: true false false true true。s4是一个新的引用,这个引用和s5一样,但是和s3不同。也就是说,intern的时候创建了一个新的对象。但是不是每次都新建一个,只要有了,就会返回存在的。最后两个结果就说明了这点。
4. 垃圾回收
GC是不会收集Literal Pool的。但是会收集没有intern的String 变量对象。对上面的例子,s3会被回收,s4就不会。
5. constant expression - 常量表达式
常量表达式,比如 "ab" + "cabc"会被当成literal,也就等同"abcabc"。
6. 关于其他的Literal呢?
If the value p being boxed is true, false, a byte, or a char in the range \u0000
to \u007f, or an int or short number between -128 and 127 (inclusive), then let
r1 and r2 be the results of any two boxing conversions of p. It is always the case
that r1 == r2.
也就是说,他们是部分重用的。看一个例子:
1. String Literal Constant Pool
引用
By literal we mean any number, text, or other information that represents a value. This means what you type is what you get.
literal,就是字符串,数字等值本身。当你在编码的时候写下一个值的时候,比如10,或者“abc”你就写了一个literal。
JVM 维护了一个String Literal Pool,用来存储String Literal。
引用
A string literal consists of zero or more characters enclosed in double quotes.
A string literal is a reference to an instance of class String. Moreover, a string literal always refers to the same instance of class String.
A string literal is a reference to an instance of class String. Moreover, a string literal always refers to the same instance of class String.
字符串字是一个由双引号括起来的字符序列。它是指向一个String实例的引用。
比如 String s = “abc”。对于“abc”,它首先是一个String literal,它在创建之后,立即利用String的intern方法,装入到了Literal Pool并返回这个String 实例的引用给s。当你再次写abc”的时候,intern方法会先查看是否已有这个literal了,就会直接返回这个literal对应的String实例的引用。也就是说你循环1000变,内存里面也只有这么一个String literal以及他对应的String的实例。String,本质上是一个Java 类,它的实例除了包含value,也就是这个字符序列外,还有其他的属性和方法。这样看来String Object和Literal本质上是不同的。
其实除了String Literal,还有其他类型的Literal:
引用
- IntegerLiteral
- FloatingPointLiteral
- BooleanLiteral
- CharacterLiteral
- StringLiteral
- NullLiteral
只是,只有String Literal有这么一个pool,用来提高性能和节约内存。提高性能,是因为你可以重用已经有的String Object,这样也就节约了内存。
再来看看 new String("abc"), 只有用了双引号,就会涉及到string literal,它的逻辑就是先查看是否已有这个literal,有就返回它的string object 引用,没有就创建一个,并生成一个string的object,然后把这个object的引用返回。可见,没有string literal有且仅有一个string object与之对应。回到这句话,new String("abc"),只有用到new,就会新建一个object,这里是新建一个string object。这就都明白了吧。看一个例子:
package jdk.lang; public class StringTest { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2); } }
输出 true。也就是只生成了一个对象。
2. 编译时计算和运行时计算的区别
看下面:
package jdk.lang; public class StringTest { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; String s3 = s1 + s2; String s4 = "abc" + "abc"; String s5 = "ab" + "cabc"; System.out.println(s3 == s4); System.out.println(s4 == s5); } }
输出:false true。上面的程序,"abc" + "abc"是常量运算表达式constant expression。编译器就可以计算出值了,这就是编译时计算。同时这个表达式会被看做是string literal。但是:String s3 = s1+s2;那么s3的值就只能在运行的时候才能确定,这就是运行时计算。可见运行时会创建一个新的String,并且不会被当成string literal。
3. Intern
下面是String的intern方法的注释和签名,可见是一个native方法。
引用
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
All literal strings and string-valued constant expressions are interned.
public native String intern();
String提供了方法Intern让我们把显示的调用来把String对象放入到literal pool里面并返回这个新的引用。
package jdk.lang; public class StringTest { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; String s3 = s1 + s2; String s4 = s3.intern(); String s5 = "ab" + "cabc"; System.out.println(s4 == s5); System.out.println(s3 == s5); System.out.println(s3.intern() == s3); System.out.println(s3.intern() == s4); System.out.println(s5.intern() == s5); } }
输出: true false false true true。s4是一个新的引用,这个引用和s5一样,但是和s3不同。也就是说,intern的时候创建了一个新的对象。但是不是每次都新建一个,只要有了,就会返回存在的。最后两个结果就说明了这点。
4. 垃圾回收
GC是不会收集Literal Pool的。但是会收集没有intern的String 变量对象。对上面的例子,s3会被回收,s4就不会。
5. constant expression - 常量表达式
引用
Compile-time constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern.
常量表达式,比如 "ab" + "cabc"会被当成literal,也就等同"abcabc"。
6. 关于其他的Literal呢?
引用
If the value p being boxed is true, false, a byte, or a char in the range \u0000
to \u007f, or an int or short number between -128 and 127 (inclusive), then let
r1 and r2 be the results of any two boxing conversions of p. It is always the case
that r1 == r2.
也就是说,他们是部分重用的。看一个例子:
private static void IntegerLiteral() { Integer i1 = 6; Integer i2 = 6; Integer i3 = 3 + 3; Integer i4 = 3 * 2; System.out.println(i1 == i2);//true System.out.println(i3 == i2);//true System.out.println(i4 == i2);//true Integer i5 = 128; Integer i6 = 128; System.out.println(i5 == i6);//false } private static void BoolearnLiteral() { Boolean b1 = true; Boolean b2 = true; System.out.println(b1 == b2);//false }
发表评论
-
Spring 源码学习 - ClassPathXmlApplicationContext
2012-05-06 11:47 6676众所周知,Spring以其强大而又灵活的IoC管理功能著称。I ... -
从appfuse开始学习Spring和Hibernate - (2)Spring启动log
2012-05-05 21:35 2354分析appfuse的详细的启动日志来看看Spring的启动过程 ... -
从appfuse开始学习Spring和Hibernate - (1)构建项目
2012-05-05 15:54 6381千里之行,始于足下。结合例子学习概念,比较靠谱。本文介绍如何开 ... -
Spring 事务在多线程环境下的传播
2012-05-04 21:42 8786有时候需要使用多线程来提高对于CPU,尤其是多核CPU的利用率 ... -
关于Hashtable和HashMap, Vector和ArrayList
2012-05-01 09:41 1907在功能上讲Hashtable和HashMap, Vector和 ... -
JVisualVM还真是不错
2012-04-27 21:38 1607最近再看Java 性能的问题。一直都习惯使用Jconsole和 ... -
Java Management Extensions (JMX) 学习笔记- 程序管理和监控
2012-04-07 20:25 4204在学习Tomcat 7 的源代码的时候发现,大量运用到了JMX ... -
Tomcat 7 源码分析 - 初始化 class loader
2012-04-07 19:24 2387Bootstrap 在启动的时候初 ... -
Tomcat 7 源码分析 - 启动概览 bootstrap
2012-04-07 14:57 2350先大致浏览一下整个启 ... -
Tomcat 7 源码分析 - 下载 tomcat source code 并导入eclipse
2012-04-07 09:23 17409准备好好研究学习一下tomcat 7 的源代码,那么第一步就是 ... -
Java Generic 学习
2012-04-06 19:34 1537泛型是Java 5开始引入的一个语言级别的特性 ... -
Java 执行过程详解 - JVM 生命周期
2012-04-04 12:01 8633Java的执行过程也就是JVM从启动到退出的过程。JVM的运行 ... -
Java System 类详解 - properties and environment variables
2012-04-04 11:32 2471在环境配置中我们经常需要知道或者设置系统属性值和环境变量。系统 ... -
Java System 类详解 - arraycopy
2012-04-04 11:01 2502System类提供了数组copy函数: public ... -
Java System 类详解 - in, out, err
2012-04-04 07:46 10444几乎所有的都用过这个System类吧,因为大家学习的第一个语句 ... -
关于 sun.misc.Unsafe
2012-04-03 15:31 4585今天在看java.util.concurrent.atomic ... -
如何提高代码质量
2012-04-02 20:08 1154本文是写给开 ... -
在Java中什么是 Primitive 和 Reference 类型
2012-03-24 23:14 2836Java虽然是个面向对象的语言,也声称“Everything ... -
Java 并发编程 - Programming Concurrency on the JVM
2012-03-24 23:08 3450这几个月一直在做性能调优的工作,以前总是进行功能的开发,从来不 ... -
如何进行Java EE性能测试与调优
2012-03-24 20:51 1299性能测试的目标 性能 ...
相关推荐
001-glib-gdate-suppress-string-format-literal-warning.patch 001-glib-gdate-suppress-string-format-literal-warning.patch 001-glib-gdate-suppress-string-format-literal-warning.patch
作为打字稿插件安装套件yarn add ts-string-literal-enum-plugin或npm i ts-string-literal-enum-plugin 更新tsconfig { " compilerOptions " : { " plugins " : [{ " name " : " ts-string-literal-enum-plugin " ,...
template-literal-源码.rar
css-literal-loader, 将CSS标记的模板文本解析为CSS文件 css-literal-loader用于提取和处理其他文件中定义的css的web pack加载器和babel插件。"inline CSS",它只适用于 CSS 。PostCSS 。LESS 。tlb或者任何它的他...
String, String>} 的对象,可以通过下面的方式实现: * {@literal Map<String, String> map = GenericUtils.getMap() }。但是不能直接作为参数使用,例如有这样一个方法: * {@literal setInfo(Map<...
Test that the clearing of object literal when normalizing objects works.
udemy--typescript-union-literal-type-alias-interface-void。 好的
项目中有个定时任务,每天取到一些表...EOL while scanning string literal: <string>, line 1, pos 7 google一下,这个异常造成的原因是字符串,引号没有成对出现,也就是类似下面的情况 复制代码 代码如下: str(
String[] imports = {"java.util.Date", "java.util.Random"}; for(String imp : imports){ //创建一个新包声名 ImportDeclaration importDeclaration = ast.newImportDeclaration(); //添加包说明 ...
前端开源库-json-literalJSON文字,超集
python库。资源全名:ae_literal-0.2.31.tar.gz
awesome-template-literal-types:精选模板真文字类型示例的清单
mysql 数据库数据赋给js变量报unterminated string literal错误原因
esformatter-literal-notation 将数组和对象构造函数转换为文字符号的插件 var foo = new Array ( ) ;// converted to:var foo = [ ] ;var bar = new Object ( ) ;// converted to:var bar = { } ;安装用做: $ npm ...
适用qt5.9 win 环境下 protobuf 3.16 源码加已编译的静态库
水犯规 Waterfoul是用Ruby-lang编写的Gameboy模拟器。 我自己可以随意学习设备的内部结构及其工作原理。 入门 要启动仿真器: bundle exec exe/waterfoul start ... RUBYOPT="--enable-frozen-string-literal --j
$ npm install --save template-literal-table 出口 导出以下函数 名称 描述 default default导出,这是table table 表格解析器,跳过分隔行(单元格仅包含两个或更多-字符)和由空单元格组成的行 empty 表解析...