• JVM—Java内存结构


    JAVA虚拟机内存

    JAVA虚拟机内存,也叫JAVA内存,可以理解为Java虚拟机运行时数据区。

     

    JVM内存结构

    包括: 线程共享的方法区 和 堆, 以及每个线程私有的 JAVA栈,本地方法栈 和 PC计数器(程序计数器)。

     

    JAVA堆

    堆,是JAVA虚拟机中所管理的内存中最大的一块,此内存区域的唯一目的就是存放对象实例以及数组

    所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。

     

    JAVA堆与垃圾回收的渊源

      JAVA堆也是垃圾回收器管理的主要区域,因此也被称为:"GC堆"。

      从内存回收的角度看,由于现在的收集器基本都采用分代收集算法,所以JAVA堆中还可以细分为:新生代和老生代

    再细致一点的划分如下:新生代又被进一步划分为Eden和 From Survivor区,最后From  Survivor由FromSpace和

    ToSpace组成。

     

    • 新生代新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例。
    • 旧生代:用于存放新生代中经过多次垃圾回收仍然存活的对象。

     

    JAVA虚拟机规范对JAVA堆的规定

      JAVA堆可以处于物理上的不连续的内存空间中,只要逻辑上是连续的即可。在实现时,即可以实现成固定大小的,

    也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx 和 -Xms 控制)。

    关于OutOfMemoryError异常 :

    如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

     PS:OutOfMemoryError 有时简称为 OOM异常

     

    JAVA栈(也叫做 虚拟机栈)

      每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法

    调用过程中的临时变量、参数和中间结果。

     

    注意:JAVA栈是为JAVA方法服务的,本地方法栈是为Native方法服务的。

    JAVA虚拟机规范中,对JAVA栈这个区域规定了两种异常状况:

    • 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError
    • 如果JAVA栈可以动态扩展,但是扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

    与JAVA栈一样,本地方法栈区域也会抛出 StackOverflowError 和 OutOfMemoryError 异常。

    PS:Native方法是指用其他语言写的方法,在JAVA中只能调用。

    本地方法栈

      用于支持native方法的执行,存储了每个native方法调用的状态。

     

    方法区

      方法区和JAVA堆一样,是各个线程共享的内存区域。

      存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。JVM用持久代(PermanetGeneration)

    来存放方法区,可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。

      JAVA虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与

    JAVA堆区分开来。

  • 相关阅读:
    【bzoj2962】序列操作 线段树
    【bzoj1922】[Sdoi2010]大陆争霸 堆优化Dijkstra
    .NET Core / C# 开发 IOT 嵌入式设备的个人见解
    C#中Equals和= =(等于号)的比较)
    VS 2017常用快捷键
    【你不一定知晓的】C#取消异步操作
    工程实践:给函数取一个"好"的名字
    接口测试入门篇
    博客园知名博主 Vamei 英年早逝!
    人生苦短,我用 Python
  • 原文地址:https://www.cnblogs.com/Mokaffe/p/4883728.html
Copyright © 2020-2023  润新知