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);
}
}