# 4.JVM知识
[TOC]
> 《深入理解Java虚拟机:JVM高级特性与最佳实践(最新第二版)》
### JVM运行时内存区域划分
线程独享区域:程序计数器,本地方法栈,虚拟机栈
线程共享区域:元空间(<=1.7方法区), 堆
程序计数器:线程私有,是一块较小的内存空间,可以看做是当前线程执行的字节码指示器,也是唯一的没有定义OOM的区块
本地方法栈: 用于执行Native 方法时使用
虚拟机栈:用于存储局部变量,操作数栈,动态链接,方法出口等信息
元空间:存储已被虚拟机加载的类元信息,常量,静态变量,即时编译器编译后的代码等数据依旧存储在方法区中,方法区位于堆中
堆:存储对象实例
**元空间OOM示例:**
```java
/**
* @author: jujun chen
* @description: 使用了CGLIB来动态生成类,元空间存储类信息,-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
* 如果只设置堆的大小,并不会溢出
* @date: 2019/4/7
*/
public class JavaMetaSpaceOOM {
static class OOMObject{}
public static void main(final String[] args) {
while (true){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMObject.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return methodProxy.invokeSuper(o,objects);
}
});
enhancer.create();
}
}
}
```
**虚拟机栈OOM**
```java
//SOE栈异常 -Xss125k
public class SOETest() {
static int count = 0;
public static void main(String[] args) {
try {
stackMethod();
} catch(Error err) {
err.printStackTrace();
System.out.println("执行count=" + count);
}
}
private static void stackMethod() {
count ++;
stackMethod();
}
}
```
**堆OOM**
```java
//OOM -Xmx20m -Xms20m -XX:+HeapDumpOnOutOfMemoryError
public class OOMTest {
public static void main(String[] args) {
List