Java面试题冲刺第二十七天--JVM2
1. 内存模型
Java内存模型主要分为两种:
- 堆内存:存放我们new出来的对象以及数组等,这部分内存可以动态申请或释放。一般情况下,堆内存比较大。
- 栈内存:存放基本类型的变量以及对象的引用变量(指针),这些变量会随着程序的运行而申请或释放。栈的空间比较小,一般情况下,栈的大小是在程序启动的时候就固定下来。
2. JVM内存模型
JVM内存模型主要分为五种:
- 方法区(JDK7及以前称为永久代):存放静态变量、类信息等,这部分内存可以动态申请或释放。运行时类的情况是在方法区中存储。
- 堆内存:同上。
- 虚拟机栈:与线程相关的数据存储在虚拟机栈中,包括方法调用的局部变量、返回值等数据。这个是栈内存的一部分。
- 本地方法栈:较少使用,主要是为了支持本地(native)方法。
- PC寄存器:记录当前线程执行的代码行号,也就是JVM中的“程序计数器”。
3. GC算法
- 新生代GC:一般采用复制算法。
- 老年代GC:一般采用标记-清除算法。
在JDK 1.2之后,Java默认使用的是能够自动适应应用程序所需的并行垃圾收集器(Parallel Collector)——也称之为吞吐量优先收集器(The throughput collector)。
4. 分代收集
对于JVM的“分代收集”策略,一般分为以下几步:
- 对于新生代开辟一段内存,称之为“Eden”空间;
- 运行过程中,将对象放入Eden空间;
- 当Eden空间满时,将其中存活的对象,复制到其他内存空间,称之为“Survivor”空间中;
- 当“Survivor”空间也满时,将存活下来的对象放入老年代空间;
- 老年代也满,就会触发Full GC,也就是对整个堆都进行清理。
5. 示例说明
示例1
public class Test {
private static int count = 0;
public static void main(String[] args) {
checkMemory();
}
private static void checkMemory(){
while (true){
new Thread(() -> {
byte[] array = new byte[1024 * 1024];
try {
Thread.sleep(1000);
count++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
System.out.println("count=" + count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这段代码实现了不断开启新的线程进行内存分配操作。在输出中,你会看到类似如下的内容:
count=985
count=987
count=999
Exception in thread "Thread-2" java.lang.OutOfMemoryError: Java heap space
这是因为每当开启一个新线程时,都会在堆内存中占用一定空间。由于没有使用相关手段对线程进行回收,最终导致堆内存耗尽。
示例2
public class Test {
private static int count = 0;
public static void main(String[] args) {
while (true){
new Thread(() -> {
byte[] array = new byte[1024 * 1024];
try {
Thread.sleep(1000);
count++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
System.out.println("count=" + count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这段代码与示例1非常相似,唯一的区别就是while循环在main方法中而不是checkMemory方法中。在输出中,你会看到类似如下的内容:
count=390
count=411
count=422
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
这是因为main方法一直处于运行状态,并在其中使用while循环不断加入新线程,最终导致堆内存耗尽。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java面试题冲刺第二十七天–JVM2 - Python技术站