25.虚拟机栈的一些面试题目、GC和OOM在哪个内存区域出现
目录
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); } }