黑马程序员技术交流社区

标题: 【成都校区】-Java内存模型(堆、栈) [打印本页]

作者: 小刀葛小伦    时间: 2019-4-4 14:47
标题: 【成都校区】-Java内存模型(堆、栈)
栈区:
栈分为java虚拟机栈和本地方法栈
①重点是Java虚拟机栈,它是线程私有的,生命周期与线程相同。
②每个方法执行都会创建一个栈帧,用于存放局部变量表,操作数栈,动态链接,方法出口等。每个方法从被调用,直到被执行完,对应着一个栈帧在虚拟机中从入栈到出栈的过程。
③ 通常说的栈就是指局部变量表部分,存放编译期间可知的8种基本数据类型,及对象引用和指令地址。局部变量表是在编译期间完成分配,当进入一个方法时,这个栈中的局部变量分配内存大小是确定的。
④ 会有两种异常StackOverFlowError和OutOfMemoryError。当线程请求栈深度大于虚拟机所允许的深度就会抛出StackOverFlowError错误;虚拟机栈动态扩展,当扩展无法申请到足够的内存空间时,抛出OutOfMemoryError。
⑤ 本地方法栈与虚拟机栈的区别是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,
而本地方法栈则为虚拟机使用到的Native方法服务。

堆区:
① 堆被所有线程共享区域,在虚拟机启动时创建,唯一目的存放对象实例。
② 堆区是GC的主要区域,通常情况下分为两个区块年轻代和老年代。更细一点年轻代又分为Eden区,放新创建对象,From survivor和To survivor保存gc后幸存下的对象,默认情况下各自占比8:1:1。
③ 会有异常OutOfMemoryError

方法区
① 被所有线程共享区域,用于存放已被虚拟机加载的类信息,常量,静态变量等数据,被Java虚拟机描述为堆的一个逻辑部分,习惯也叫它永久代(Permanent Generation)
② 垃圾回收很少光顾这个区域,不过也是需要回收的,主要针对常量池回收,类卸载。
③ 常量池具有一定的动态性,里面可以存放编译期生成的常量;运行期间的常量也可以添加进入常量池中,比如String的intern()方法。

程序计数器
① 当前线程所执行的行号指示器。通过改变计数器的值来确定下一条指令,比如循环,分支,跳转,异常处理,线程恢复等都是依赖计数器来完成的。
② Java虚拟机多线程是通过线程轮流切换并分配处理器执行时间的方式实现的。为了线程切换能恢复到正确的位置,每条线程都需要一个独立的程序计数器,所以它是线程私有的。
③ 唯一一块Java虚拟机没有规定任何OutOfMemoryError的区域




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2