1. 内存模型、分区,理解多少?
1.1 栈区
栈: Java虚拟机栈和本地方法栈, 被称为工作内存的地方。
重要描述下 Java虚拟机栈特点:线程私有,线程安全,生命周期和线程相同。
1.1.1 每个方法被调用,都会创建一个栈帧,包含有局部变量表、操作栈、动态链接、方法返回地址,附加信息。 如果方法被调用,就是栈帧入栈到出栈的过程。
1.1.2 如果方法中还有调用其它方法,是同理的,也是创建栈帧,如上图,多个栈帧被压入栈后,都遵循着栈的特性: 先进后出。
1.1.3 局部变量表:8种基本数据类型,对象引用,指令地址。编译阶段栈帧大小已经确定。所以在被调用的时候,栈中局部变量分配内存大小是确定的。
1.1.4 Java虚拟机栈异常种类:StackOverFlowError 和 OutOfMemoneyError。如:递归调用,栈的深度大于虚拟机栈的深度,就会抛出StackOverFlowError错误。OutOfMemoneyError这个异常好理解,就是内存不够申请一个栈帧占用的空间时间抛出。
1.1.5 优点:存取速度快,仅次于寄存器。
1.1.6 缺点:数据大小与生存期必须确定,缺乏灵活性。
1.1.7 共享: 栈中的数据可以共享。 如: int s1 = 1; int s2 = 1; 会先找是否有1这个值,如果有进引用指向这个值。这个引用不会互相影响,这个是由编译器完成,为了节省空间。在如:String str = "abc";这种写法一定程度上提高运行速度。这种写法并不一定都创建了对象,也有可能只是引用了对象。
1.2 堆区
堆:是所有线程共享的区域,被称为 主存的地方
1.2.1 特点:线程不安全,对象实例集中地,gc的主战场。
1.2.2 分代: 年轻代,年老代。
1.2.3 年轻代:Eden区,From区,To区,默认比例大小,8:1:1。对象诞生和消亡比较快速,默认gc 8次还存活的对象,被迁移到年老代。
1.2.4 年老代: 对象比较活跃区,引用一直存在,不容易被gc
1.2.5 异常:OutOfMemoneyError
1.3 方法区
方法区:是所有线程共享的区域
1.3.1 特点: 线程不安全
1.3.2 存放: 虚拟机加载的类信息,常量池,静态变量,字面量。
1.3.3 GC: 很少被GC,主要针对是常量池回收,类卸载。
1.3.3 常量池: 字节码、符号引用,及运行期间常量进入。
1.3.4 字面量:字符串,final变量,类名和方法名。
1.3.5 符号引用:类和接口的权限定名、字段的名称和描述符、方法的名称和描述符。
1.4 程序计数器
程序计数器: 行号指示器。
1.4.1 指令: 循环,分钟,跳转,异常处理,线程恢复等。
1.4.2 特点: 线程安全
1.4.3 异常: 不存在 OutOfMemoneyError(唯一区)
1.5 本地方法栈
本地方法栈: 为虚拟机使用到的Native方法服务。