zoukankan      html  css  js  c++  java
  • Java内存空间知识点梳理

    1. java内存空间,如下图所示(2张图基本大同小异)

     

     2. 运行时数据区:

    JVM 在 Java 程序运行时把它所管理的内存划分为几个不同的数据区域。分别为堆、方法区、java虚拟机栈(平常被称为的 "栈"、空间较小)、本地方法栈和程序计数器(PC计数器)。

    其中,

      堆和方法区 是所有线程共享;

      虚拟机栈、本地方法栈和程序计数器为每个线程独享。即每个线程对应的是图2中浅蓝色的部分(java栈、本地方法栈、程序计数器),java栈会对调用的每个方法生成一个栈帧。

    3.

    Java 堆对于大部分应用来说都是 JVM 所管理的内存中最大的一块。Java 堆是 所有线程共享 的一块内存区域,在虚拟机启动时创建。Java 堆的唯一的目的就是存放对象实例,几乎所有的对象实例都在这里分配内存 -- 所有的对象实例以及数组都要在堆上分配。即new出的实例都在堆上

    Java 堆的分配可以在物理上不连续的内存空间,只要逻辑上连续就可以,可以固定大小,也可以扩展空间。

    Java 堆是 GC 发生的主要区域。

    注意:堆是线程共享是指这块区域是所有线程共享,并非堆上的数据共享
     
    4. 方法区
    方法区与 Java 堆一样是所有线程共享的内存空间,它用于储存已被虚拟机加载的类信息、常量、静态常量、即时编译器编译后的代码等数据。Java 虚拟机把方法区描述为堆的一个逻辑部分,但是它还有一个别名 -- Non-Heap(非堆),目的应该是与 Java 堆区分。
      4.1 运行区常量池: 
    运行区常量池是方法区的一部分。 Class 文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是 常量池 ,用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法去的运行时常量池中存放。
     

    类的所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域,静态变量+常量+类信息(构造方法/接口定义)+运行时常量池都存在方法区中,虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。


    5. java虚拟机栈

    Java 虚拟机栈是线程私有的,其生命周期与线程相同。

    虚拟机栈描述的是 Java 方法执行的内存模型: 每个 Java 方法执行的同时都会创建一个 栈帧(stack frame) 用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

    平时的把 Java 内存分为 堆内存(heap) 和 栈内存(stack) 的分类方法是比较粗糙的,实际分类方法十分复杂。这种分类方法中栈即为虚拟机栈,或为虚拟机中的局部变量表。

    局部变量表存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(不等同于对象本身,可能是一个对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)和returnAddress(指向一条字节码指令的地址)。

    局部变量表所需的内存空间在编译期间分配完成,当进入一个方法时,这个方法需要在栈帧中分配多的的局部变量空间是完全确定的,在方法的运行期间不会改变局部变量表的大小。

    6. 本地方法栈
    本地方方法栈与虚拟机栈发挥的作用相似,不同的是该栈为 Native 方法服务。
     
    7. 程序计数器

    程序计数器是一块较小的内存,它可以看作 ++当前线程++ 所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器的工作就是通过改变这个 ++计数器的值++ 来选取下一条需要执行的字节码,分支、循环、跳转、异常处理、线程恢复等基础功能都需要这个计数器来完成

    如上图所示,程序计数器是线程私有的。

    正在执行 java 方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如 果还是 Native 方法,则为空。

     
     
     
    参考:
    https://www.jianshu.com/p/7b0804f361e7
    https://www.cnblogs.com/chengpeng15/p/9835617.html
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    第十八章、使用集合
    第十九章、枚举集合
    第十七章、泛型概述
    第十六章、使用索引器
    第十五章、实现属性以访问字段
    第十四章、使用垃圾回收和资源管理
    第十三章、创建接口和定义抽象类
    AtCoder Grand Contest 018 E
    AtCoder Regular Contest 059 F Unhappy Hacking
    Codeforces 464E. The Classic Problem
  • 原文地址:https://www.cnblogs.com/suntingme/p/15324281.html
Copyright © 2011-2022 走看看