虚拟机栈-方法调用

栈概述:
方法调用过程:
Java 栈与数据结构上的栈有着类似的含义,它是一块线程私有先进后出的数据结构,只支持出栈和入栈两种操作。在Java 枝中保存的主要内容为栈帧。每一次函数调用,都会有一个对应的栈帧被压入Java 栈,每一个函数调用结束,都会有一个栈帧被弹出Java栈。参数,-Xss 来指定线程的最大栈空间,这个参数也直接决定了函数调用的最大深度。
由于每次函数调用都会生成对应的核帧,从而占用一定的栈空间,因此,如果栈空间不足,那么函数调用自然无法继续进行下去.当请求的我深度大于最大可用栈深度时,系统就会抛出StackOverflowError 栈溢出错误.

栈帧组成:
局部变量表:
局部变量表是栈帧的重要组成部分之一。它用于保存函数的参数以及局部变量。局部变量表中的变量只在当前函数调用中有效,当函数调用结束后,随着函数栈帧的销毁, 局部变量表也会随之销毁。由于局部变量表在找帧之中, 因此,如果函数的参数和局部变量较多, 会使得局部变量表膨胀,从而每一次函数调用就会占用更多的战空间, 最终导致函数的嵌套调用次数减少。
操作数栈:
它主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。
帧数据区:
Java 栈帧需要一些数据来支持常量池解析、正常方法返回和异常处理等。大部分Java 字节码指令需要进行常量地访问,在帧数据区中保存着访问常量
池的指针,方便程序访问常量池。当函数返回或者出现异常时,虚拟机必须恢复调用者函数的栈帧,并让调用者函数继续执行下去。对于异常处理,虚拟机必须有一个异常处理表,方便在发生异常的时候找到处理异常的代码,因此异常处理表也是帧数据区中重要的一部分。一个典型的异常处理表如下图:
这里写图片描述
它表示在字节码偏移量4~ 16 字节可能抛出任意异常,如果遇到异常,则跳转到字节码偏移19 处执行。当方法抛出异常时,虚拟机就会查找类似的异常表来进行处理,如果无法在异常表中找到合远的处理方法,则会结束当前函数调用,返回调用函数,并在调用函数中抛出相同的异常,井查找调用函数的异常表进行处理。
栈上分配:
栈上分配是Java 虚拟机提供的一项优化技术,它的基本思想是:对于那些线程私有的对象(这里指不可能被其他线程访问的对象),可以将它们打散分配在栈上,而不是分配在堆上(大对象除外)。分配在栈上的好处是可以在函数调用结束后自行销毁,而不需要垃坡回收器的介入,从而提高系统的性能。栈上分配的一个技术基础是进行逃逸分析。逃逸分析的目的是判断对象的作用域是否有可能逃逸出函数体
参数-XX:+EliminateAllocations 开启了标量替换(默认打开),允许将对象打散分配在栈上,比如对象拥有id 和name 两个字段,那么这两个字段将会被视为两个独立的局部变量进行分配。

对象分配过程:

1.编译器通过逃逸分析,确定对象是在栈上分配还是在堆上分配。如果在栈上分配,则直接在栈上分配。如果是在堆上分配,则进入选项2.
2.如果tlab_top + size <= tlab_end,则在在TLAB上直接分配对象并增加tlab_top 的值(优先TLAB分配),如果现有的TLAB不足以存放当前对象则3.
3.重新申请一个TLAB,并再次尝试存放当前对象。如果放不下,则4.
4.在Eden区加锁(这个区是多线程共享的),如果eden_top + size <= eden_end则将对象存放在Eden区,增加eden_top 的值,如果Eden区不足以存放,则5.
5.执行一次Young GC(minor collection),经过Young GC之后,如果Eden区任然不足以存放当前对象,则直接分配到老年代。

TLAB分配 :
JVM在内存新生代Eden Space中开辟了一小块线程私有的区域,称TLAB(Thread-local allocation buffer)。 默认设定为占用Eden Space的1%。在Java程序中很多对象都是小对象且用过即丢,它们不存在线程共享也适合被快速GC,所以对于小对象通常JVM会优先分配在TLAB上,并且TLAB上的分配由于是线程私有所以没有锁开销。
因此在实践中分配多个小对象的效率通常比分配一个大对象的效率要高。也就是说,Java中每个线程都会有自己的缓冲区称TLAB,每个TLAB都只有一个线程可以操作,在对象分配的时候不用锁住整个堆,而只需要在自己的缓冲区分配即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值