本人最近正在面试,然后注意到总是有公司喜欢考String的问题,如字符串连接有几种方式,它们之间有什么不同等问题:要不就是给一段代码问创建了几个对象.那么该不该问呢?我认为当面试有一定工作经验的求职者时还是应该问问这个问题的,应届生就不要为难他们了还是多考考底层基础比较好.下面我结合JVisualVM和javap这两个工具来详细解析下JVM内部是怎么处理String对象的. 一.字符串常量池(String Constant Pool) 字符串在java程序中被大量使用,为了避免每次都创建相同的字…
在前面一片文章<JVM内部细节之一:synchronized关键字及实现细节>中已经提到过偏向锁的概念,在理解什么是偏向锁前必须先理解什么是轻量级锁(Lightweight Locking).引入偏向锁是为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径,因为轻量级锁的获取及释放依赖多次CAS原子指令,而偏向锁只需要在置换ThreadID的时候依赖一次CAS原子指令(由于一旦出现多线程竞争的情况就必须撤销偏向锁,所以偏向锁的撤销操作的性能损耗必须小于节省下来的CAS原子指令的性能消耗)…
在C程序代码中我们可以利用操作系统提供的互斥锁来实现同步块的互斥访问及线程的阻塞及唤醒等工作.然而在Java中除了提供Lock API外还在语法层面上提供了synchronized关键字来实现互斥同步原语.那么到底在JVM内部是怎么实现synchronized关键子的呢? 一.synchronized的字节码表示: 在java语言中存在两种内建的synchronized语法:1.synchronized语句:2.synchronized方法.对于synchronized语句当Java源代码被ja…
开发十年,就只剩下这套架构体系了! >>>   在上一博文Class文件中,我们了解了Class文件的一些基础知识.他的整个内部结构就是一张很大的表,我们就是从这张表入手,一一分析每个部分的结构.继续看这张表:     接着上一博文所说,魔数后面分别是次版本号和主版本号.由上图可知其分别占用两个字节.     被蓝色框框住的就是次版本号,划红线的就是主版本号.再次说明,Class文件内部的数据是按照规则紧凑排列的,中间不会有空隙.    接下来就是说明常量的个数了.代表着常量池中有多少个…
String的基本特性 String:字符串,使用一对""引起来表示. String sl = "hello"://字面量的定义方式: String s2 = new String("hello") : String类是已经被声明为final的, 不可被继承. String实现了Serializable接口:表示字符串是支持序列化的. 实现了Comparable接口:表示String可以比较大小 String在jdk8及以前内部定义为“priva…
从一道面试题开始 看到这个标题,你肯定以为我又要讲这道面试题了 // 这行代码创建了几个对象? String s3 = new String("1"); 是的,没错,我确实要从这里开始 这道题就算你没做过也肯定看到,总所周知,它创建了两个对象,一个位于堆上,一个位于常量池中. 这个答案粗看起来是没有任何问题的,但是仔细思考确经不起推敲. 如果你觉得我说的不对的话,那么可以思考下面这两个问题 你说它创建了两个对象,那么这两个对象分别是怎样创建的呢?我们回顾下Java创建对象的方式,一共就…
作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么? 字符串常量池的设计思想是什么? 字符串常量池在哪里? 如何操作字符串常量池? 字符串常量池的设计思想 字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能 JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化 为字符串开辟一个字符串常量池,类似于缓存区 创建字符串常量时,首…
一.String的基本特性 String:字符串,使用一对 "" 引起来表示 String s1 = "atguigu" ; // 字面量的定义方式 String s2 = new String("hello"); // new 对象的方式 String被声明为final的,不可被继承 String实现了Serializable接口:表示字符串是支持序列化的.实现了Comparable接口:表示String可以比较大小 String在jdk8及以…
大家都清楚java中String类是不可变的,它的定义中包含final关键字.一旦被创建,值就不能被改变(引用是可以改变的). 但这种“不可变性”不是完全可靠的,可以通过反射机制破坏.参考一下代码: String str = "abc"; System.out.println(str); Field field = String.class.getDeclaredField("value"); field.setAccessible(true); char[] va…
运行时常量池是方法区(PermGen)的一部分. 需要提前了解: 1. JVM内存模型. 2. JAVA对象在JVM中内存分配 常量池的好处 常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享. - Java的自动装箱中其实就使用到了运行时常量池.详见:Java 自动装箱与拆箱的实现原理 - 还有字符串常量池. 字符串进入到常量池的两种方法: 1. new String()的实例调用intern()方法.     执行intern()方法时,若常量池中不存在等值的字符串,JV…