面试之 Java内存模型
1. Java内存模型
1.1. Java内存模型
Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。
1.2. Jvm内存模型
1.2.1. 堆
所有对象实例及数组都要在堆上分配内存。但随着JIT编译器的发展和逃逸分析技术的成熟,可将这些变量直接在栈上进行分配。它是所有线程共享的区域,也是gc的主要区域。
默认情况下对大小为1/64~1/4。通过-Xms(最小值)和-Xmx(最大值)参数设置,一般都设置相等,服务器一般内存都足够。以避免堆大小的伸缩带来的性能损耗。
堆内存 = 新生代+老生代+持久代,默认新生代和老生代(大小比例1:2,新生代=Eden+Eden和Survivor0,Survivor1组成,三者的比例是8:1:1
新生代的回收机制采用复制算法,老生代采用的回收算法是标记整理算法
1.2.2. 方法区
是所有线程共享的内存区域,为了区分堆,又被称为非堆,用于存储已被虚拟机加载的类信息、常量、静态变量。
运行时常量池,是方法区的一部分,存放编译期间生成的各种字面量和符号引用。
方法区也称"永久代",jdk1.8,已经移除,取而代之是元空间(Metaspace),可以通过MaxMetaspaceSize进行设置,但是受限本地内存,默认是根据运行时动态调整
1.2.3. 栈
## 描述的是java方法执行的内存模型
##每个方法被调用到执行完的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。声明周期与线程相同,是线程私有的,
##栈帧由三部分组成:局部变量区、操作数栈、帧数据区
1.2.4. 程序计数器
由于cpu运行速度极快,可以同时处理多个线程,在线程切换,切换的时候需要知道线程执行到哪里了。程序计数器是唯一个不会内存溢出的地方。
1.2.5. 本地方法区
调用c或者c++代码地方