• JVM 运行时数据区 (三)


    JVM运行时数据区

    运行时数据区由 程序计数器、java虚拟机栈、本地方法栈、堆、方法区 组成;

    1、程序计数器

      每一个Java线程都有一个程序计数器,用于保存程序执行到当前方法的哪一个指令,它是线程私有的。

    此内存区域是唯一一个在VM Spec中没有规定任何OutOfMemoryError情况的区域。

    2、Java虚拟机栈

      通常说的栈指的就是Java栈,主管Java程序的运行。栈是在线程创建时创建,线程结束栈内存就释放掉了,不存在垃圾回收问题,线程一结束该栈就Over,与程序计数器一样,它的生命周期也是与线程相同,它是线程私有的

      基本类型的变量、实例方法、引用类型变量都是在函数的栈内存中分配

      栈描述的是Java方法调用的内存模型:每个方法被执行的时候,都会同时创建一个帧(Frame)用于存储本地变量表、操作栈、动态链接、方法出入口等信息。每一个方法的调用至完成,就意味着一个帧在VM栈中的入栈至出栈的过程。本地变量表存放了编译期可知的各种标量类型(boolean、byte、char、short、int、float、long、double)、对象引用(不是对象本身,仅仅是一个引用指针)、方法返回地址等

      这个区域规定了2种异常:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果VM栈可以动态扩展(VM Spec中允许固定长度的VM栈),当扩展时无法申请到足够内存则抛出OutOfMemoryError异常。

    (1)抛出StackOverflowError异常的代码(递归调用):

    public class StackDemo1
    {
        static void sayHello()
        {
            System.out.println("AAAAA");
            sayHello();
        }
    
        public static void main(String[] args) {
            sayHello();
        }
    }

    3、本地方法栈

      本地方法栈和Java虚拟机栈发挥的作用是类似的,只不过Java虚拟机栈为虚拟机运行原语服务,而本地方法栈是为虚拟机使用到的 native 服务。

    它的实现语言、结构、方式没有强制规定,甚至有的虚拟机把它和java虚拟机栈合二为一了,例如Sun Hotspot

      和java虚拟机栈一样,这个区域也会抛出StackOverflowError异常和OutOfMemoryError异常。

    4、堆

      Java7之前

        一个JVM实例只存在于一个堆内存中,堆内存的大小是可以调节的。类加载器读取了类文件之后,需要把类、方法、常变量放到堆内存中,

      保存所有引用类型的真实信息,以方便执行器执行。

        堆内存逻辑上分为:新生区、养老区、永久区。(实际上永久区被称为非堆内存)

        新生区:伊甸区(Eden Space)、幸存0区(Survivor 0 Space)、幸存1区(Survivor 1 Space)

        当new 一个对象,该对象被放入伊甸区(Eden),创建的对象越来越多,伊甸区(Eden)快满的时候启动一种轻垃圾回收(Minor GC),未被回收的对象被放入幸存0区(Survivor 0),Eden被清空;当幸存0区快满了,未被回收的对象被放入幸存1区(Survivor 1),Survivor 0和Eden被清空;Survisor 0与Survivor 1交换角色,如此循环往复。如果对象的复制次数达到16次,该对象就会被送到养老中。当养老区快满的时候触发一个重量级的GC(Major GC),清理之后还是无法再保存对象,就会产生OOM异常(OutOfMemoryError)。

        Survisor 0 和 Survivor 1会一直调换角色,谁是空的谁就是Survivor 1区。

             

        

        

    5、方法区

      方法区是所有线程共享的,通常用来储存装载的类的元结构信息。垃圾回收很少发生;

      比如:运行时常量池 + 静态变量 + 常量 + 字段 + 方法字节码 + 在类/实例/接口初始化用到的特殊方法等。

      通常和永久区关联在一起(Java7),具体的跟JVM的实现和版本有关。Java8以后,变为了MetaSpace(元空间),直接使用的物理内存,垃圾回收运行的概率变得更低。

     

  • 相关阅读:
    排序算法之希尔排序
    javascript Set data structures
    javascript Dictionary data structures
    javascript linkedlist data structures
    关于Java Collections的几个常见问题
    java NIO中的buffer和channel
    编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。如:ABCABCABC…… 依次递归
    Java多线程之Callable接口的实现
    Java并发:volatile内存可见性和指令重排
    Lock和synchronized的区别和使用
  • 原文地址:https://www.cnblogs.com/yufeng218/p/9158664.html
Copyright © 2020-2023  润新知