程序计数器(PC)和对象创建

1. 程序计数器:

1. 是什么 : 是一块较小的内存,可以看成字节码行号指示器。

2. 干什么 : 通过改变计数器的值来获取下一条需要执行的字节码。为每个线程都分配一个程序计数器,因此,程序计数器的内存空间是线程私有的(java是支持多线程的当CPU执行A线程的时候就会挂起B线程,执行完B线程,在执行A线程。CPU不会记住A线程执行到那个位置。他只会埋头苦干,而时程序计数器来记录当前线程执行的字节码的行号)

3. 创建时间 : 程序计数器在线程被创建的时候就会被一起创建。

4. 特性 : 程序计数器只保存的当前执行的字节码的偏移地址,所以程序计数器永远不会内存溢出

2. java虚拟机栈

1. Java虚拟机栈也是线程私有的,生命周期和线程相同

2. 每个方法在执行的时候会创建一个栈帧,用于存储局部变量,操作数栈等信息

3. 64位长度的long和double会占用两个局部变量空间。其余数据类型占用一个

4. 局部变量表所需要的内存空间在编译期间完成分配,当进入一个方法时这个方法需要在桢 中分配的内存空间是完全可以确定的,在方法运行期间不会改变局部变量表的大小

5. 有两种异常情况:

 a. 当请求的栈深度大于虚拟机允许的深度。将抛出StackOverflowError(局部变量表内容越多,栈帧越大,栈深度越小。)
 b. 当扩展时无法申请到足够的内存,就会抛出OutOfMenoryError异常。

3. 对象的创建

1. 先定位这个指令参数是否能在常量池中定位到一个类的符号好引用,并检查这个类是否已经被加载,解析,初始化,如果没有那就先加载

2. 在类加载完成后,虚拟机将为新生对象分配内存,对象所需要的内存大小在加载完成后就可以完全确定。

3. java内存分配的两种方式 :

a. 指针碰撞: 如果java内存时绝对规整的。空闲的内存放在一边,用过的内存放在一边,中间放着指针作文分界的指示器。那分配内存就是空闲内存向另一边挪动一段与对象大小相同的距离。这种就是"指针碰撞"。
b. 空闲列表: 如果内存时不规整的,空闲内存和用过的内存相互交错。那就没有方法进行"指针碰撞",那虚拟机必须维护一个列表记录那些内存是可用的。在分配时从列表中找到一快足够大的空间划分给实例对象。并更新列表。这种分配时空闲列表。
总结: 采用哪种分配方式是Java是否规整决定的。Java是否规整又是由垃圾回收器是否带有压缩整理功能决定的。因此在使用serial,ParNew,带有Compact过程的收集器。采用的是指针碰撞。而使用CMS这种基于Mark-Sweep算法的收集器时。通常采用空闲列表。

4. 对象访问的两种方式

1. 句柄访问,那么在java堆中将会划分出一块内存来作为句柄,reference中存储的就是对象的句柄地址。

2. 直接指针访问,那么java堆对象的布局就必须考虑如何放置访问类型的数据相关信息,而reference中存储的直接就是对象地址

3. 总结

a. 句柄访问优点: reference中的存储的是稳定的句柄地址,在对象被移动(垃圾回收时移动对象是非常普遍的行为)的时候只会改变实例数据指针,而reference本身不需要改变。
b. 直接指针访问优点: 最大的好处就是速度快。它节省了一次指针定位的时间开销。
总结: java使用的时直接指针访问。但是再软件开发中句柄访问也是很常见的。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值