首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

常量和堆区别_字符串常量在堆中还是方法

采用字面值方式创建字符串对象 采用new关键字新建一个字符串对象 字符串优缺点 4.字符串常量和运行时常量之间藕断丝连 常量字符串常量版本变化 String.intern...在JDK6和JDK7之后区别(重难点) 字符串常量池里存放引用还是字面量 1.常量 常量,也叫 Class 常量(常量==Class常量)。...看下面两张图: 在堆中字符串常量: **堆里边字符串常量存放字符串引用或者字符串(两者都有)**下面例子会有具体讲解 符号引用表会在下面讲 我们知道,在Java中有两种创建字符串对象方式...str1引用,这样,str1指向了堆中创建这个”aaa”字符串对象。...另外美团团队写了一篇关于intern()博客,我觉得很好可以参考一下 深入解析String#intern 4.3字符串常量池里存放引用还是字面量 我在例子3中讲了在JDK7中字符串常量在堆上

1.1K30

几张图轻松理解String.intern()

其实要搞明白String.intern(),我总结了下面几条规则:  一、new String都是在堆上创建字符串对象。...当调用 intern() 方法时,编译器会将字符串添加到常量池中(stringTable维护),并返回指向该常量引用。  ? ?...六、JDK 1.7后,intern方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中引用,这一点与之前没有区别,区别在于,如果在常量找不到对应字符串,则不会再将字符串拷贝到常量,...而只是在常量池中生成一个对原字符串引用。...简单说,就是往常量东西变了:原来在常量池中找不到时,复制一个副本放到常量,1.7后则是将在堆上地址引用复制到常量。  ?

51810
您找到你想要的搜索结果了吗?
是的
没有找到

【面试题精讲】你了解String.intern方法

---- String.intern 方法是 Java 中一个方法,「它用于将字符串对象添加到字符串常量池中,并返回常量池中该字符串引用。...如果常量池中已经存在该字符串,则直接返回常量池中引用」。 在 Java 中,字符串常量是一块特殊内存区域,用于存储字符串常量。...使用 String.intern 方法可以手动如果字符串常量池中已经存在相同内容字符串,则直接返回常量池中引用字符串对象添加到字符串常量池中。...str2 是使用字面量创建字符串对象,它在字符串常量池中分配空间。str3 是通过 String.intern 方法将 str1 添加到字符串常量池中得到引用。...需要注意是,由于字符串常量是在运行时创建,因此在使用 String.intern 方法时需要谨慎使用,以避免过多字符串对象被添加到常量池中,导致内存占用过大。

14940

Java 常见内存溢出异常与代码实现

上面是一个引发 OutOfMemoryError 异常代码, 我们可以看到, 它就是通过不断地创建对象, 并将对象保存在 list 中防止其被垃圾回收, 因此当对象过多时, 就会使堆内存溢出。...String.intern() 方法作用是: 若此 String 值在常量池中已存在, 则这个方法返回常量池中对应字符串引用; 反之将此 String 所包含添加到常量池中, 并返回此 String...注意, 上面所说 String.intern() 方法和常量内存分布仅仅针对于 JDK 1.6 及之前版本, 在 JDK 1.7 或以上版本中, 由于去除了永久代概念, 因此内存布局稍有不同...下面是实现常量池内存溢出代码例子: ? 我们看到, 这个例子中, 正是使用了 String.intern() 方法, 向常量池中添加了大量字符串常量, 因而导致了常量内存溢出....我们还是以上面提到例子为例: ?

89920

Java 常见内存溢出异常与代码实现

上面是一个引发 OutOfMemoryError 异常代码, 我们可以看到, 它就是通过不断地创建对象, 并将对象保存在 list 中防止其被垃圾回收, 因此当对象过多时, 就会使堆内存溢出。...String.intern() 方法作用是: 若此 String 值在常量池中已存在, 则这个方法返回常量池中对应字符串引用; 反之将此 String 所包含添加到常量池中, 并返回此 String...注意, 上面所说 String.intern() 方法和常量内存分布仅仅针对于 JDK 1.6 及之前版本, 在 JDK 1.7 或以上版本中, 由于去除了永久代概念, 因此内存布局稍有不同...下面是实现常量池内存溢出代码例子: ? 我们看到, 这个例子中, 正是使用了 String.intern() 方法, 向常量池中添加了大量字符串常量, 因而导致了常量内存溢出....我们还是以上面提到例子为例: ?

77530

字符串留用与字符串

(1)、Intern方法用于获取一个String,获得它哈希码,并在哈希表中检查是否有相匹配,如果存在完全相同字符串,就返回对现有String对象应用.如果不存在全完相同字符串,就创建字符串副本....将副本添加到内部哈希表中,返回对该副本引用.如果应用程序不再保持对原始String对象引用,这时垃圾回收器就会介入,将字符串内存强行释放掉....String,并在内部哈西表中查找它.如果哈西表中有匹配字符串,IsInterned方法就返回对这个留用字符串对象应用.但如果没有,IsInterned就返回null,不会将字符串添加到哈希表中....,代码如下: //去内部哈希表中检查是否有xiaochao字符串,有的话返回该字符串引用,反之,创建字符串副本,返回该副本引用. str = String.Intern(str); //去内部哈希表中检查是否有...引用字符串所有代码都被修改成引用元数据中同一个字符串.编译器将单个字符串多个实例合并成一个实例,能显著减少模块大小.C/C++编译器多年来一直采用这个技术,这个技术被称为"字符串".

75720

String.intern() 方法有什么作用?

当调用 intern 方法时,如果字符串常量池中已经存在该字符串,那么返回池中字符串;否则将此字符串添加到字符串常量池中,并返回字符串引用。...JDK1.6 和 JDK1.7 在 intern() 方法实现上,有相同,也有不同。 相同点: 先去查看字符串常量是否有该字符串,如果有,则返回字符串常量池中引用。...不同点: 如果是 JDK1.7,当字符串常量池中找不到对应字符串时,不会将字符串拷贝到字符串常量,而只是生成一个对该字符串引用字符串常量。而 JDK1.6 会拷贝字符串字符串常量。...JDK1.6 中,常量方法区。JDK1.7 中,常量移到堆区了。 ? 注意:字符串常量池中 String 对象,也是可以被 GC 回收,只要它不再被引用了。...String.intern 方法可以减少内存中相同字符串数量,节省一些内存空间。

4.1K30

String类和常量池内存分析例子以及8种基本类型

2 String 类型常量比较特殊。它主要使用方法有两种: 直接使用双引号声明出来 String 对象会直接使用或创建常量池中对应字符串。...说说String.intern() String.intern() 是一个 Native 方法,它作用(在JDK1.6和1.7操作不同)是: 如果运行时常量池中已经包含一个等于此 String 对象内容字符串...,则直接返回常量池中该字符串引用; 如果没有, 那么 在jdk1.6中,将此String对象添加到常量池中,然后返回这个String对象引用(此时引用串在常量)。...方法,那么此次字符串常量获取结果将是一个指向相同String实例引用。...以下所说常量字符串常量。 接下来我们均以示例方式来解释问题,也是我在某篇文章底下解决别人问题笔记。 可能最颠覆你认知是问题八,所以既然来看了,还是建议看到最后吧!

20620

JVM各区溢出分析

这两种异常有一些重叠部分:当栈空间无法继续分配时,到底是内存太小,还是已经使用栈空间过大,其本质只是对同一件事情两种不同描述。...0x03: 方法区和运行时常量溢出 由于运行时常量属于方法一部分,因此两个区域放在一块执行。...String.intern()是一个Native方法,它作用是如果字符串常量池中已经包含了此String对象字符串,则返回代表池中这个字符串String对象;否则将此String对象包含字符串添加到常量池中...实现不会复制实例,只是在常量池中记录首次出现实例引用,因此intern()返回引用和由StringBuilder创建那个字符串实例是同一个。...方法区用于存放Class相关信息,如类名、访问修饰符、常量、字段描述、方法描述等,对于这些区域测试,基本思路是运行时产生大量类填充方法区,直到溢出。

48120

String 既然能这样性能调优,我直呼内行(文末送书)

字符串常量指的是在创建字符串时候,先去「常量」查找是否创建过该「字符串」; 如果有,则不会开辟新空间创建字符串,而是直接把常量池中该字符串引用返回给此对象。...String 对象,同时该对象指向「常量」中“码哥字节”字符串,str 指向刚刚在堆上创建 String 对象; 如下图(str1、str2): ❝什么是对象和对象引用呀?...str 属于方法字面量,它指向堆中 String 对象,并不是对象本。 对象在内存中是一块内存地址,str 则是指向这个内存地址引用。 也就是说 str 并不是对象,而只是一个对象引用。...这是因为 str 只是 String 对象引用,并不是对象本身。 真正对象依然还在内存中,没有被改变。...否则将此字符串添加到常量池中,并返回字符串引用。 如果不包含此字符串,先将字符串添加到常量池中,再返回此对象引用。 ❝什么情况下适合使用 intern() 方法

41620

Nacos源码中为什么使用了String.intern方法

在intern方法上有一段注释来介绍它功能,大意是:当调用intern方法时,如果字符串常量池中不存在对应字符串(通过equals方法比较),则将该字符串添加到常量池中;如果存在则直接返回对应地址。...这两种形式字符串创建在内存分布上是有区别的。 直接使用双引号创建字符串时,会先去常量查找该字符串是否已经存在,如果不存在的话先在常量创建常量对象,然后返回引用地址;如果存在,则直接返回。...JDK1.7实现 JDK1.7后,intern方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中引用,与之前没有区别。...但如果在常量找不到对应字符串,则不会再将字符串拷贝到常量,而只是在常量池中生成一个对原字符串引用。 简单说,就是往常量内容变了。...原来在常量池中找不到时,复制一个副本放到常量,1.7后则是将堆上地址引用复制到常量,也就是常量存放是堆中字符串引用地址。 1.7及以后,常量已经从方法区中移出来到了堆中。

30210

String:字符串常量

String:字符串常量 作为最基础引用数据类型,Java 设计者为 String 提供了字符串常量以提高其性能,那么字符串常量具体原理是什么,我们带着以下三个问题,去理解字符串常量字符串常量设计意图是什么...为字符串开辟一个字符串常量,类似于缓存区 创建字符串常量时,首先坚持字符串常量是否存在该字符串 存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中 实现基础...在常量池中查找是否有“abc”对象 有则返回对应引用实例 没有则创建对应实例对象 在堆中 new 一个 String(“abc”) 对象 将对象地址赋值给str4,创建一个引用...str1 == str2" : str1 == str2 ) //true String.intern() 通过new操作符创建字符串对象不指向字符串池中任何对象,但是可以通过使用字符串intern...同样会生成一个新字符串,但内部字符数组引用常量池里边字符串内部字符数组,意思是和u是同样字符数组 使用图来表示的话,情况就大概是这样(使用虚线只是表示两者其实没什么特别的关系):

68310

java面试强基(9)

2、如果字符串常量池中已存在字符串对象“abc”引用,则只会在堆中创建 1 个字符串对象“abc”。 intern 方法有什么作用?  ​ ...String.intern() 是一个 native(本地)方法,其作用是将指定字符串对象引用保存在字符串常量池中,可以简单分为两种情况: 如果字符串常量池中保存了对应字符串对象引用,就直接返回该引用...如果字符串常量池中没有保存了对应字符串对象引用,那就在常量池中创建一个指向该字符串对象引用并返回。 尽管在输出中调用intern方法并没有什么效果,但是实际上后台这个方法会做一系列动作和操作。...在调用”ab”.intern()方法时候会返回”ab”,但是这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串引用,否则就将这个字符串添加到字符串池中,然会返回这个字符串引用...,并且通过b.intern() == d和b.intern() == f可知,字符串相加时候,都是静态字符串结果会添加到字符串,如果其中含有变量(如f中e)则不会进入字符串池中。

29020

java高并发锁3种实现

中级技巧 - String.intern() 乐观锁不能很好解决大量写冲突问题,但是如果很多场景下,锁实际上只是针对某个用户或者某个订单。比如一个用户必须先创建session,才能进行后面的操作。...使用String.inter()是这种思路一种具体实现。类 String 维护一个字符串。...当调用 intern 方法时,如果已经包含一个等于此 String 对象字符串(该对象由 equals(Object) 方法确定),则返回池中字符串。...当我们读取共享数据时候,直接读取,不需要同步。当我们修改数据时候,我们就把当前数据Copy一份副本,然后在这个副本 上进行修改,完成之后,再用修改后副本,替换掉原来数据。...高级技巧 - 类ConcurrentHashMap String.inter()缺陷是类 String 维护一个字符串是放在JVM perm区,如果用户数特别多,导致放入字符串String不可控

3K30

一个高频面试题,考考大家对 Java String 常量理解。

字符串开辟一个字符串常量,类似于缓存区 创建字符串常量时,首先坚持字符串常量是否存在该字符串 存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中 实现基础 实现该优化基础是因为字符串是不可变...: str1 == str2 ) //true 字符串常量在哪里 在分析字符串常量位置时,首先了解一下堆、栈、方法区: 堆 存储是对象,每个对象都包含一个与之对应class JVM只有一个堆区...方法区 静态区,跟堆一样,被所有的线程共享 方法区中包含都是在整个程序中永远唯一元素,如class,static变量 字符串常量则存在于方法区 代码:堆栈方法区存储字符串 String str1...在常量池中查找是否有“abc”对象 有则返回对应引用实例 没有则创建对应实例对象 在堆中 new 一个 String("abc") 对象 将对象地址赋值给str4,创建一个引用 所以,常量池中没有“...new操作符创建字符串对象不指向字符串池中任何对象,但是可以通过使用字符串intern()方法来指向其中某一个。

83520

Java基础系列2:深入理解String类

主要包括如下五个内容: String概览 “+”连接符解析 字符串常量 String.intern()方法解析 String、StringBuffer与StringBuilder String概览...由于s1,s2,s3字符串值都是在常量池中同一个引用,所以intern()方法返回值是相等。...JDK1.7改动将String常量 从 Perm 区移动到了 Java Heap区String.intern() 方法时,如果存在堆中对象,会直接保存对象引用,而不会重新创建对象。..."ABC"字符串,找到了就不会创建"ABC"字符串,找不到才会去创建"ABC"字符串;如果不使用intern方法,则没有去常量查找过程,会直接创建"ABC"字符串。...对象会直接存储在常量池中; String对象intern方法会得到字符串对象在常量池中对应引用,如果常量池中没有对应字符串,则该字符串将被添加到常量池中,然后返回常量池中字符串引用字符串+

61030

如何构造jvm堆溢出和栈溢出

首先我们要分清楚产生OutOfMemoryError异常原因是内存泄露还是内存溢出,如果内存中对象确实都必须存活着而不像上面那样不断地创建对象实例却不使用该对象,则是内存溢出,而像上面代码中情况则是内存泄露...栈溢出 虚拟机栈用于存储局部变量表、操作数栈、常量引用等信息。...根据以上存放数据,让其内存溢出只需要大量添加其中数据 比如比较容易实现向运行时常量池中字符串常量添加字符串常量 我们可以通过String.intern()方法来构建一个运行时常量OutOfMemoryError...String.intern()是一个Native方法,它作用是:如果字符串常量池中已经包含了一个等于该String对象字符串,则返回这个String对象,否则,将此String对象包含字符串添加到常量池中...,并返回这个字符串String对象引用

1.3K30

String性能提升10倍几个方法!(源码+原理分析)

,这样它就更加高效,并且更适合做 HashMap key- value 缓存; 节约内存:String 不可变性是它实现字符串常量基础,字符串常量指的是字符串创建时,先去“常量”查找是否有此...当代码中使用第一种方式创建字符串对象时,JVM 首先会检查该对象是否在字符串常量池中,如果在,就返回该对象引用,否则新字符串将在常量池中被创建。...2.善用 intern 方法 善用 String.intern() 方法可以有效节约内存并提升字符串运行效率,先来看 intern() 方法定义与源码: /** * Returns a canonical...,它定义中说是,当调用 intern 方法时,如果字符串常量池中已经包含此字符串,则直接返回此字符串引用,如果不包含此字符串,先将字符串添加到常量池中,再返回此对象引用。...,所以不会复制字符串副本只是会把首次遇到字符串引用添加到常量池中。

1.1K20

教妹学 Java 第 35 讲:intern

三妹委屈地说,“哥,还是你亲自给我讲讲吧?” “好吧,上次学字符串常量你都搞清楚了吧?” “嗯。”三妹微微点了点头。...这个变化也直接影响了 String.intern() 方法在执行时策略,Java 7 之前,执行 String.intern() 方法时候,不管对象在堆中是否已经创建字符串常量池中仍然会创建一个内容完全相同新对象...;Java 7 之后呢,由于字符串常量放在了堆中,执行 String.intern() 方法时候,如果对象在堆中已经创建了,字符串常量池中就不需要再创建对象了,而是直接保存堆中对象引用,也就节省了一部分内存空间...第一行代码,字符串常量池中会先创建一个“二哥三妹”对象,然后堆中会再创建一个“二哥三妹”对象,s1 引用是堆中对象。...第二行代码,对 s1 执行 intern() 方法,该方法会从字符串常量池中查找“二哥三妹”这个字符串是否存在,此时是存在,所以 s2 引用字符串常量池中对象。

43210
领券