关于 栈相关的面试题
-
举例栈溢出的情况?StackOverflowError
可以通过-Xss设置栈大小 如果方法的调用过深,导致设置的栈大小不足会抛出栈溢出,
如果没有设置栈大小动态扩充栈大小的话,在内存不存的情况下栈已经申请不到更多的内存空间会出现OOM异常
-
调整栈大小就能保证不出现栈溢出吗?
不能,通过调整栈大小可以延缓栈溢出的时间或者说减少栈溢出的风险。比如一个业务逻辑的方法调用需要5000次,但此时抛出栈溢出,通过-Xss设置更大的栈空间使得调用在7000次才会溢出,此时调整栈大小就有意义使得业务能正常支持,如果是有死递归的情况则无论怎么提高栈大小都会溢出
-
分配栈的内存是不是越大越好?
不是,可能会造成空间浪费,会挤占其他线程的空间。因为整个计算机的内存是有限的,将栈空间设置过大,会导致每一个线程线程更加占用资源,导致计算机能开辟的线程就会减少
-
垃圾回收会不会涉及虚拟机栈
不会,因为虚拟机栈只有简单的push 和 pop操作 pop出去之后就相当于回收了不需要专门的垃圾回收
-
方法中定义的局部变量是否线程安全?
具体问题具体分析
总而言之,如果对象是在内部产生且在内部消亡,不会返回到外部就不存在线程安全问题,反之如果类本身线程不安全的话就存在线程安全问题
package runtimedataarea.jvmstack.interview; /** * @author : Jim Wu * @version 1.0 * @function : * @since : 2020/9/16 16:41 */ public class ThreadSafeProblem { /** * 线程安全的 虽然StringBuilder本身线程不安全 * 但s1 变量只存在于这个栈帧的局部变量表中,栈帧是每个线程独立的一份 * 所以这里的s1是线程安全的 */ public static void method01() { // 线程内部创建的,属于局部变量 StringBuilder s1 = new StringBuilder(); s1.append("a"); s1.append("b"); } /** * 线程不安全 * 因为此时方法将StringBuilder返回出去了 * 外面的其他线程可以直接修改StringBuilder这个引用了所以不安全 * @return */ public static StringBuilder method04() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("a"); stringBuilder.append("b"); return stringBuilder; } /** * 线程不安全 * 因为此时StringBuilder是作为参数参数 * 外部的其他线程也可以访问 所以线程不安全 * @param 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是线程安全的 * 此时sb值在当前栈帧的局部变量表中存在,其他线程无法访问到该引用 * 方法执行完成之后此时局部变量表中的stringBuilder的就销毁了 * 返回的stringBuilder.toString()线程不安全 * 最后的返回值将toString返回之后,其他线程可以操作而String本身是线程不安全的 * @return */ public static String method05() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("a"); stringBuilder.append("b"); return stringBuilder.toString(); } }
-
运行时数据区,是否存在Error和GC
运行时数据区 是否存在Error 是否存在GC 程序计数器 否 否 虚拟机栈 是 StackOverFlow OOM 否 本地方法栈 是 OOM 否 方法区 是 OOM 是 堆 是 OOM 是