## 一、内存结构
### 1.程序计数器
#### 1.1定义
#### 1.2作用
记住下一条JVM指令的执行地址
特点:
1.线程私有
2.不会存在内存溢出
### 2.虚拟机栈
#### 2.1 定义
每个线程运行时需要的内存成为虚拟机栈
每个栈由多个栈帧组成,对应着每次方法调用多占用的内存
每个线程只能有一个活动栈帧,对应当前正在执行的那个方法。
栈:线程运行时需要的内存
栈帧:每个方法运行时需要的内存(参数、局部变量、返回地址等)
问题:
垃圾回收是否涉及栈内存? 不需要,会释放掉。
栈内存分配越大越好吗? 不是,线程数会减少,例如有500M内存,每个栈内存给1M,可以有500个线程。反之。
方法内的局部变量是否线程安全? 看局部变量是共享的还是私有的。
#### 2.2 栈内存溢出
1.递归没有合理终止
2.互相引用
#### 2.3线程运行诊断
1.CPU占用过高:用top命令定位哪个进程,用ps H -oe pid,tid,%cpu打印。jstack查看进程。
2.程序运行很久没有结果。可能是线程死锁。
### 3.方法区
#### 3.1 定义
#### 3.2 组成
#### 3.3 方法区内存溢出
#### 3.4 运行时常量池
常量池就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息。
运行时常量池,常量池是*.class文件中的当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址。
#### 3.5 String Table
常量池中的字符串只是符号,第一次用到时变为对象
利用串池机制,来避免重复创建字符串对象
字符串变量拼接的原理是stringTable
字符串常量拼接的原理是编译器优化
可以使用intern方法,主动将串池中还没有的字符串对象放入串池。
#### 3.6 String Table位置
<img src="C:\Users\77579\AppData\Roaming\Typora\typora-user-images\image-20210705171527055.png" alt="image-20210705171527055" style="zoom:150%;" />
#### 3.7 String Table 垃圾回收
#### 3.8 String Table性能调优
- 调整 String TableSize = 桶个数