基于Java中字符串内存位置详解

 更新时间:2016年08月18日 09:14:23   投稿:jingxian  
下面小编就为大家带来一篇基于Java中字符串内存位置详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

前言

之前写过一篇关于JVM内存区域划分的文章,但是昨天接到蚂蚁金服的面试,问到JVM相关的内容,解释一下JVM的内存区域划分,这部分答得还不错,但是后来又问了Java里面String存放的位置,之前只记得String是一个不变的量,应该是要存放在常量池里面的,但是后来问到new一个String出来应该是放到哪里的,这个应该是放到堆里面的,后来又问到String的引用是放在什么地方的,当时傻逼的说也是放在堆里面的,现在总结一下:基本类型的变量数据和对象的引用都是放在栈里面的,对象本身放在堆里面,显式的String常量放在常量池,String对象放在堆中。

常量池的说明

常量池之前是放在方法区里面的,也就是在永久代里面的,从JDK7开始移到了堆里面。这一改变我们可以从oracle的release version的notes里的** Important RFEs Addressed in JDK 7 **看到。

Area: HotSpot
Synopsis: In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.
RFE: 6962931

String内存位置说明

1.显式的String常量

String a = "holten";
String b = "holten";

•第一句代码执行后就在常量池中创建了一个值为holten的String对象;

•第二句执行时,因为常量池中存在holten所以就不再创建新的String对象了。

•此时该字符串的引用在虚拟机栈里面。

1.String对象

String a = new String("holtenObj");
String b = new String("holtenObj");

•Class被加载时就在常量池中创建了一个值为holtenObj的String对象,第一句执行时会在堆里创建new String("holtenObj")对象;

•第二句执行时,因为常量池中存在holtenObj所以就不再创建新的String对象了,直接在堆里创建new String("holtenObj")对象。

验证一下

/**
 * Created by holten.gao on 2016/8/16.
 */
public class Main {
  public static void main(String[] args){
    String str1 = "高小天";
    String str2 = "高小天";
    System.out.println(str1==str2);//true
    
    String str3 = new String("高大天");
    String str4 = new String("高大天");
    System.out.println(str3==str4);//false
  }
}

返回结果:

true
false

以上这篇基于Java中字符串内存位置详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 如何利用java中String类的substring()字符串截取最后一个字符

    如何利用java中String类的substring()字符串截取最后一个字符

    Java中的String是不可变的类型,因此substring()方法并不会改变原字符串,而是返回了一个新的字符串,这篇文章主要介绍了如何利用java中String类的substring()字符串截取最后一个字符,需要的朋友可以参考下
    2023-11-11
  • 一文让你搞懂如何手写一个redis分布式锁

    一文让你搞懂如何手写一个redis分布式锁

    既然要搞懂Redis分布式锁,那肯定要有一个需要它的场景。高并发售票问题就是一个经典案例。本文就来利用这个场景手写一个redis分布式锁,让你彻底搞懂它
    2022-11-11
  • JDBC查询Map转对象实现过程详解

    JDBC查询Map转对象实现过程详解

    这篇文章主要介绍了JDBC查询Map转对象实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java Annotation Overview详解

    Java Annotation Overview详解

    这篇文章主要介绍了Java Annotation Overview,需要的朋友可以参考下
    2014-02-02
  • jar包中替换指定的class文件方法详解

    jar包中替换指定的class文件方法详解

    这篇文章主要为大家介绍了jar包中替换指定的class文件方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • SpringBoot中的定时任务和异步调用详解

    SpringBoot中的定时任务和异步调用详解

    这篇文章主要介绍了SpringBoot中的定时任务和异步调用详解,SpringBoot 定时任务是一种在SpringBoot应用中自动执行任务的机制,通过使用Spring框架提供的@Scheduled注解,我们可以轻松地创建定时任务,需要的朋友可以参考下
    2023-10-10
  • Dwr3.0纯注解(纯Java Code配置)配置与应用浅析二之前端调用后端

    Dwr3.0纯注解(纯Java Code配置)配置与应用浅析二之前端调用后端

    我们讲到了后端纯Java Code的Dwr3配置,完全去掉了dwr.xml配置文件,但是对于使用注解的类却没有使用包扫描,而是在Servlet初始化参数的classes里面加入了我们的Service组件的声明暴露,对于这个问题需要后面我们再细细研究下这篇文章,主要分析介绍前端怎么直接调用后端
    2016-04-04
  • java设计模式-装饰者模式详解

    java设计模式-装饰者模式详解

    这篇文章主要介绍了Java设计模式之装饰者模式详解和代码实例,Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案,需要的朋友可以参考下
    2021-07-07
  • 利用javaFX实现移动一个小球的示例代码

    利用javaFX实现移动一个小球的示例代码

    这篇文章主要介绍了利用javaFX实现移动一个小球的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Java数据结构之图的两种搜索算法详解

    Java数据结构之图的两种搜索算法详解

    在很多情况下,我们需要遍历图,得到图的一些性质。有关图的搜索,最经典的算法有深度优先搜索和广度优先搜索,接下来我们分别讲解这两种搜索算法,需要的可以参考一下
    2022-11-11

最新评论