千家信息网

通过面试题虚拟机栈的方法技巧

发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,本篇内容主要讲解"通过面试题虚拟机栈的方法技巧",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"通过面试题虚拟机栈的方法技巧"吧!众所周知,栈只有进栈和出栈两
千家信息网最后更新 2025年01月21日通过面试题虚拟机栈的方法技巧

本篇内容主要讲解"通过面试题虚拟机栈的方法技巧",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"通过面试题虚拟机栈的方法技巧"吧!

众所周知,栈只有进栈和出栈两种操作,所以它是一种快速有效的分配存储方式。对于它来说,它不存在垃圾回收问题,但是它的大小是动态的或者固定不变的,因此它会存在栈溢出或者内存溢出问题......

面试官: 打断一下啊,你刚才说会存在栈溢出和内存溢出问题,那你能分别说一下为什么会出现这种情况吗?

阿Q: 可以可以,我们知道虚拟机栈由栈帧组成,每一个方法的调用都对应着一个栈帧的入栈。我们可以通过-Xss参数来设置栈的大小,假设我们设置的虚拟机栈大小很小,当我们调用的方法过多,也就是栈帧过多的话,就会出现StackOverflowError,即栈溢出问题。

假如我们的栈帧不固定,设置为动态扩展的,那在我们的内存不足时,也就没有足够的内存来支持栈的扩展,这个时候就会出现OOM异常,即内存溢出问题。

面试官: 嗯嗯(点头状),示意小伙子思路很清晰呀,那你刚才说到栈帧设置的太小会导致栈帧溢出问题,那我们设置的大点不就可以完全避免栈溢出了嘛。

阿Q: 一听就是要给我挖坑呀,像我们一般都比较崇尚中庸之道,所以一听到这种绝对的问题,必须机灵点:不不不,调整栈的大小只可以延缓栈溢出的时间或者说减少栈溢出的风险。

举个????吧
  1. 假如一个业务逻辑的方法调用需要5000次,但是此时抛出了栈溢出的错误。我们可以通过设置-Xss来获取更大的栈空间,使得调用在7000次时才会溢出。此时调整栈大小就变得很有意义,因为这样就会使得业务能正常支持。

  2. 那假如是有死递归的情况则无论怎么提高栈大小都会溢出,这样也就没有任何意义了。

面试官: 好的,那你看一下这个简单的小程序,你能大体说一下它在内存中的执行过程吗?

 public void test() {      byte i = 15;      int j = 8;      int k = i + j;}

来张图,便于大家更好地理解

阿Q: 先把该代码编译一下,然后查看它的字节码文件。如上图中左边所示,执行过程如下:

  1. 首先将要执行的指令地址0存放到PC寄存器中,此时,局部变量表和操作数栈的数据为空;

  2. 当执行第一条指令bipush时,将操作数15放入操作数栈中,然后将PC寄存器的值置为下一条指令的执行地址,即2

  3. 当执行指令地址为2的操作指令时,将操作数栈中的数据取出来,存到局部变量表的1位置,因为该方法是实例方法,所以0位置存的是this的值,PC寄存器中的值变为3;

  4. 同步骤2和3将8先放入操作数栈,然后取出来存到局部变量表中,PC寄存器中的值也由3->5->6

  5. 当执行到地址指令为678时,将局部变量表中索引位置为12的数据重新加载到操作数栈中并进行iadd加操作,将得到的结果值存到操作数栈中,PC寄存器中的值也由6->7->8->9

  6. 执行操作指令istore_3,将操作数栈中的数据取出存到局部变量表中索引为3的位置,执行return指令,方法结束。

面试官: 内心OS:这小子貌似还可以呀。说的还不错,那你能说一下方法中定义的局部变量是否线程安全吗?

阿Q: 那我再用几个例子来说一下吧。

public class LocalParaSafeProblem {    /**     * 线程安全的     * 虽然StringBuilder本身线程不安全,     * 但s1 变量只存在于这个栈帧的局部变量表中,     * 因为栈帧是每个线程独立的一份,     * 所以这里的s1是线程安全的     */    public static void method01() {        // 线程内部创建的,属于局部变量        StringBuilder s1 = new StringBuilder();        s1.append("a");        s1.append("b");    }    /**     * 线程不安全     * 因为此时StringBuilder是作为参数传入,     * 外部的其他线程也可以访问,所以线程不安全     */    public static void method02(StringBuilder stringBuilder) {        stringBuilder.append("a");        stringBuilder.append("b");    }    /**     * 线程不安全     * 此时StringBuilder被多个线程同时操作     */    public static void method03() {        StringBuilder stringBuilder = new StringBuilder();        new Thread(() -> {            stringBuilder.append("a");            stringBuilder.append("b");        }, "t1").start();        method02(stringBuilder);    }    /**     * 线程不安全     * 因为此时方法将StringBuilder返回出去了     * 外面的其他线程可以直接修改StringBuilder这个引用了所以不安全     */    public static StringBuilder method04() {        StringBuilder stringBuilder = new StringBuilder();        stringBuilder.append("a");        stringBuilder.append("b");        return stringBuilder;    }    /**     * StringBuilder是线程安全的     * 此时stringBuilder值在当前栈帧的局部变量表中存在,     * 其他线程无法访问到该引用,     * 方法执行完成之后此时局部变量表中的stringBuilder的就销毁了     * 返回的stringBuilder.toString()线程不安全     * 最后的返回值将toString返回之后,其他线程可以操作而String本身是线程不安全的。     */    public static String method05() {        StringBuilder stringBuilder = new StringBuilder();        stringBuilder.append("a");        stringBuilder.append("b");        return stringBuilder.toString();    }}

到此,相信大家对"通过面试题虚拟机栈的方法技巧"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

线程 方法 安全 变量 局部 指令 操作数 问题 内存 大小 寄存器 位置 地址 数据 技巧 业务 内容 动态 参数 可以通过 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 宁夏银川软件开发花多少钱 15项互联网领先科技成果获奖 小鹿学车服务器异常 南京勤德网络技术有限公司开庭 计算机网络安全专业能考什么证 sql数据库语句手册手机版 数据库关系er模型图 我的世界超能力电脑服务器下载 数据库开发对企业的影响 联通移动发展数据库 js数据库更新一条数据类型 网络安全与信息化委职责员会 海尔电视服务器链接错误 全球宏观经济数据库 6月1号网络安全管理法 互粉软件开发 电信网络安全等级考试题库 机房里如何手动重启服务器 推广软件开发报价含义 升级mysql数据库的命令 淘宝服务器掉线 魔兽世界各版本新增服务器 h2 数据库场景 小学生网络安全宣传语短 网络安全介绍及就业方向 服务器地址和ip 国家中小学网络安全教育 深圳社交软件开发常见问题 云服务器如何设置安全 软件开发年度优秀个人事迹
0