JVM中的内存分配(对象的存储)

Jvm中的内存分为:寄存器、栈、堆、常量池、代码段、数据段

  1. 寄存器:不可控,也是未知

  2. 栈:保存局部变量。而局部变量又包括基本类型和引用类型。对于基本类型来说其中就是保存其“值”,而对于引用类型的来说,这里存放它的地址,当一个局部变量使用完之后会被立马释放掉,但是堆区不会立马被释放。另外,局部变量是共享的,也就是说,如果栈中有int i=0,如果再出现int j=0的话,就会让j指向同一个地址。栈是由栈帧组成的,每个栈帧对应一个方法,并且保存着方法的返回地址,每个线程调用的方法不一样所以  线程之间不共享

  3. 堆:用以存放动态产生的数据,例如new出来的对象,每个对象有自己独立的堆块,其中保存着实例变量,没有方法,因为同一个类的方法都是共享的,方法只有在使用的时候才会加载到内存中,不用不会呆在内存里。堆中的数据线程之间共享。

  4. 常量池:存在于堆中。用来存放每一个类型的常量,每一个类型都对应着一个常量池。包括直接常量(基本类型和String)、对其它类型、方法、字段的符号引用。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用、所以常量池在java动态来凝结中起到了核心作用。
  5. 代码段:用来存放从硬盘读取的源程序。
  6. 数据段:用来存放static定义的静态成员。
    另一种说法:程序计数器区  栈 堆(线程之间共享数据) 本地方法栈  方法区(线程共享) (存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。

  1. 基本类型:byte short char int long boolean 存在栈区,而 其对应的包装类则 存在常量池中,也就是堆区,让门都实现了常量池技术,而double和float的没有实现,另外String也实现了常量池技术。但是常量池中维护都必须在[-128 127]
  2. 所有的局部变量都是在栈区进行运算的。
    Integer i1=20;
    Integer i2=0;
    Integer i3= new Integer(20);
    那么 i1+i2==i3 为true,因为计算i1+i2的时候,先将他们拆箱放在栈区,然后计算,计算完毕之后没有装箱,所以相当于int i4=i1+i2,所以命题为真。
  1. 常量池的数据是共享的,所以,当有一个“astring”的时候,当在定义另一个“astring”的时候弦查看常量池中有没有对应的字符串,如果没有旧添加进去,有的话就用那个。所以:
String aString="astring";
        String bString="astring";
        out.print("aString==bString\t"+(aString==bString));
        输出:aString==bString  true

但是需要注意的是由+和subString等等操作产生的字符串不是共享的,只有字符串常量是共享的。
所以:

 String aString="astring";
        String bString="astring2".substring(0,7);
        out.print("aString==bString\t"+(aString==bString));
        输出 aString==bString  false
  1. 当一个类中使用了其他的类中的符号引用是放在常量池中的,实际代码执行的时候,首次遇到某个别的类的时候,jvm会对常量池中这个类的符号引用展开转为直接引用,这样下次再遇到同样的类型的时候,jvm就不再解析,而是直接使用这个已经被解析过的直接引用
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值