首先大致回顾下内存区域的整体结构以及可能出现的异常:

对于语句
Person person = new Person();,Person的class文件存储在方法区中,对象的引用person存放在栈中,new Person()后产生的对象存储在堆中

方法区用于存储类型信息、运行时常量池、静态变量、即时编译器编译后的代码缓存等
对于类中使用
final static修饰的属性,在链接的准备阶段就被赋予值,而一般的属性需要在初始化阶段才会被赋予值(该值是在代码中显示给定的值,即显示初始化)


"psj".intern()时,如果在常量池中没有psj时,就会在运行时常量池中创建)下面图中浅绿色部分表示JVM内存



1.为什么使用元空间替换永久代?
- 为永久代设置空间大小很难确定。元空间不在JVM中而在本地内存,所以它的大小受本地内存的限制,本地内存很少出现Full GC
- 对永久代的调优十分困难
2.StringTable为什么要调整?永久代GC效率低(在Full GC的时候才会触发,即老年代内存或永久代内存不足时),导致StringTable回收效率不高,而在开发中会使用到大量字符串,很容易导致永久代内存不足。堆中会及时回收内存
3.静态引用对应的对象实体始终在堆空间中,而根据不同的JDK版本,由于静态变量存放的位置不同,该静态变量的引用可能在永久代中,也可能在堆中
static byte[] arr = new byte[1024*1024*100]; // arr根据JDK版本不同会存在不同的位置,而byte数组始终在堆中
- 1
- 2

为什么要分为新生代和老年代?为什么要有Survivor区?
https://blog.csdn.net/u013126379/article/details/115590570