有 N 个线程在执行代码,每个线程都多少会在创建对象,其中一个线程(线程1)因为代码问题在疯狂循环创建对象,会导致什么情况发生,此时如果其他线程(线程2)也要创建对象会发生什么情况。
首先,线程1会一直在堆内存中创建对象,同时线程2也可以创建对象。直到OutOfMemoryError,然后GC会,释放内存资源,然后线程1死亡,该线程被终结掉,释放该线程占用的内存空间,其他线程继续运行。
测试代码
public class ThreadTest {
public static void main(String[] args) {
new Thread(() -> {
List<byte[]> list = new ArrayList<byte[]>();
while (true) {
System.out.println(new Date().toString() + Thread.currentThread() + "==");
byte[] b = new byte[1024 * 1024 * 1];
list.add(b);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
// 线程二
new Thread(() -> {
while (true) {
System.out.println(new Date().toString() + Thread.currentThread() + "==");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
设置JVM启动参数
这是内存监控
通过内存监控我们可以发现,在达到堆内存最大值之后,报出OOM错误,然后GC回收所有的使用的堆的内存,就会产生空闲内存,然后其他线程可以继续运行。
要想运行出同样的结果,一定要把JVM参数调到足够小,不能太大,不然堆空间内存过大,很难出现同样的效果。
综上所诉,当一个线程疯狂创建对象时,再没有到达堆内存最大值时,其他线程依然可以创建对象,当堆内存满了之后,GC回收所有的对象,释放内存资源,其他线程依然可以创建对象。