目录
1.虚拟机栈面试题目
1.栈溢出的情况?
会出现StackOverflow
和OutOfMemory
异常。
栈的大小可以通过-Xss
设置。虚拟机栈可以使固定大小的或者是自动扩充的,如果是固定大小的,当栈空间不足的时候就会出现StackOverflow
;如果是可以自动扩充的,当物理内存不足以用来扩充的时候就会出现OOM
。
2.调整栈大小,就能保证不出现溢出?
不能。一个无限的递归程序,不管栈调整的多大,栈都会出现StackOverflow
。
3.分配的栈内存越大越好吗?
不是。
4.垃圾回收是否会涉及到虚拟机栈?
不会,栈只存在入栈和出栈操作,不存在GC。
存在GC
的只有堆区和方法区。
不存在OOM
的只有程序计数器。
Rutime Data Area | OOM | GC |
---|---|---|
程序计数器 | 不存在 | 不存在 |
虚拟机栈 | 存在 | 不存在 |
本地方法栈 | 存在 | 不存在 |
堆 | 存在 | 存在 |
方法区 | 存在 | 存在 |
5.方法中定义的局部变量表是否线程安全?
可能会存在线程安全的问题。
/**
* 面试题:
* 方法中定义的局部变量是否线程安全?具体情况具体分析
*
* 何为线程安全?
* 如果只有一个线程才可以操作此数据,则必是线程安全的。
* 如果有多个线程操作此数据,则此数据是共享数据。如果不考虑同步机制的话,会存在线程安全问题。
* @author shkstart
* @create 2020 下午 7:48
*/
public class StringBuilderTest {
int num = 10;
//s1的声明方式是线程安全的,因为s1只在method1被使用,只有调用该方法的一个线程才可以操作s1.
public static void method1(){
//StringBuilder:线程不安全
StringBuilder s1 = new StringBuilder();
s1.append("a");
s1.append("b");
//...
}
//sBuilder的操作过程:是线程不安全的。sBuilder是传进来的,也可能被其他线程使用。
public static void method2(StringBuilder sBuilder){
sBuilder.append("a");
sBuilder.append("b");
//...
}
//s1的操作:是线程不安全的,s1被返回出去,可能被其他的线程使用。
public static StringBuilder method3(){
StringBuilder s1 = new StringBuilder();
s1.append("a");
s1.append("b");
return s1;
}
//s1的操作:是线程安全的。toString调用new String产生了新的String,s1在方法内部消亡了,所以线程安全。但是新产生的String有可能线程不安全。
public static String method4(){
StringBuilder s1 = new StringBuilder();
s1.append("a");
s1.append("b");
return s1.toString();
}
public static void main(String[] args) {
StringBuilder s = new StringBuilder();
new Thread(() -> {
s.append("a");
s.append("b");
}).start();
method2(s);
}
}