java内存分配和String的不变性

系统 1612 0

转载请出自出处: http://eksliang.iteye.com/blog/2146549

http://eksliang.iteye.com

一.java分配内存涉及的区域包括

    1. 寄存器
    2. 常量池
    3. 静态存储域

二.寄存器介绍

      寄存器是最快的内存区域,因为他保存在处理器内部,这块区域我们没有直接的控制权,也不可能在代码里面找到寄存器的任何存在踪迹,所以这块不做讨论

 

三.常量池介绍

1.常量池是什么?

答:他是在.class文件中开避的一块内存区域,用来存储在编译期间就可以确定一些数据

       例如:String str="think";think在编译的期间就是可识别的常量,就能加进常量池

2.常量池中的数据是在什么时候加载进内存的?

答:在类被编译成.class文件时,加载进来的

3.常量池中都放些什么东西?

答:包括如下信息

  1. String类型的变量;例如String str="think",不是new String("think");
  2. 对象的常量值
  3. 类的全限类名以及他的描述符;属性的名称跟描述符;方法的名称跟描述符

4.String的不变性

1.什么是String的不变性?

答:所谓String的不可变性,是说一旦字符串被创建,对其所做的任何修改都会生成 新的 字符串对象(来源于《think in java》)

接下来看下他的源码

      public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

    /**
     * Class String is special cased within the Serialization Stream Protocol.
     *
     * A String instance is written initially into an ObjectOutputStream in the
     * following format:
     * <pre>
     *      <code>TC_STRING</code> (utf String)
     * </pre>
     * The String is written by method <code>DataOutput.writeUTF</code>.
     * A new handle is generated to  refer to all future references to the
     * string instance within the stream.
     */
    private static final ObjectStreamField[] serialPersistentFields =
            new ObjectStreamField[0];
    

 通过源码我们可以看到这个类他的所有属性,以及类都是final关键字修饰,也就是说他在内存中只有一份拷贝,也就是说当创建一个新的字符串,他会去常量池中找如果这个串存在就直接引用,如果没有就创建

例如:如下三句代码的意思是

      1)String s1="aabbcc";
2)		String s2="aabbcc";
3)		s1="aa";
    

 他的含义入下图所示:

当程序执行到(1)时如图在常量池中创建"aabbcc"


java内存分配和String的不变性
 

当程序执行到(2)时如图所示,因为已经存在了,就直接引用,(实际上内部在创建一个字符串时,他会先去变量常量池,查找看当前创建的字符串是否存在,如果存在就直接引用,没有就创建)


java内存分配和String的不变性
 

当程序执行到(3)时如图所示,因为修改了字符串s1的值,所以他会在内存中创建一个新字符串,原来指向aabbcc的指针断开,指向“aa”

 


java内存分配和String的不变性
 

四.栈

1.栈中存放的是那些数据?

答:存放基本类型的变量数据和对象的引用,但对象本身并不存放在栈中,而是存放在堆中或者常量池中(字符串、常量对象存放在常量池中)

       当在一段代码块定义一个变量时,JVM就在栈中为这个变量分配内存空间,当该变量退出该作用域后,JVM会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

2.实际存储在哪里?

答:数据驻留在RAM(随机存储器)区域;

何为随机存储器?答:是与CPU直接交换数据的内部存储器,也叫主存或者内存,它可以随时读写,而且速度很快,通常作为操作系统或正在运行中的程序的临时数据存储媒介

 

五.堆

1.存放的是那些数据?

答:存放所有new 出来的对象。或者通过反射创建的对象

2.实际数据存储在哪里?

答:数据驻留在RAM(随机存储器)区域

 

六.静态存储域

1.存放的是那些数据?

答:存放的是静态成员(static定义),这儿的静态(static)是指"位置固定位置"。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的一个属性或者方法是静态的,但是JAVA对象永远不会保持到静态存储区

 

 

 

 

  

java内存分配和String的不变性


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论