Java 内存分配-全面浅析2

文章引自:https://www.cnblogs.com/lipeineng/p/8358823.html

java的内存管理分为:

   1、堆内存; 2、栈内存; 3、方法区; 4、本地方法区

  • 方法区
    方法区存放装载的类数据信息包括:

    1. 基本信息:
      1.1 每个类的全限定名
      1.2 每个类的直接超类的全限定名(可约束类型转换)
      1.3 该类是类还是接口
      1.4 该类型的访问修饰符
      1.5 直接超接口的全限定名的有序列表

    2. 每个已装载类的详细信息:
      2.1 运行时常量池:
         存放该类型所用的一切常量(直接常量和对其它类型、字段、方法的符号引用),它们以数组形式通过索引被访问,是外部调用与类联系及类型对象化的桥梁。它是类文件(字节码)常量池的运行时表示。(还有一种静态常量池,在字节码文件中)。
      2.2字段信息:
         类中声明的每一个字段的信息(名,类型,修饰符)。
      2.3 方法信息:
         类中声明的每一个方法的信息(名,返回类型,参数类型,修饰符,方法的字节码和异常表)。
      2.4 静态变量
      2.5 到类 classloader 的引用:即到该类的类装载器的引用。
      2.6 到类 class 的引用:
         虚拟机为每一个被装载的类型创建一个 class 实例, 用来代表这个被装载的类。

  • 栈内存
    Java 栈内存由局部变量区、操作数栈、帧数据区组成。

    1. 局部变量区为一个以字为单位的数组,每个数组元素对应一个局部变量的值。调用方法时,将方法的局部变量组成一个数组,通过索引来访问。若为非静态方法,则加入一个隐含的引用参数 this,该参数指向调用这个方法的对象。而静态方法则没有this参数。因此,在静态方法里无法访问对象信息。
    2. 操作数栈也是一个数组,但是通过栈操作来访问。所谓操作数是那些被指令操
      作的数据。当需要对参数操作时如 a=b+c,就将即将被操作的参数压栈,如将 b 和 c 压栈,
      然后由操作指令将它们弹出,并执行操作。虚拟机将操作数栈作为工作区。
    3. 帧数据区处理常量池解析,异常处理等

   Java栈内存以帧的形式存放本地方法的调用状态(包括方法调用的参数,局部变量,中间结果等)。每调用一个方法就将对应该方法的方法帧压入 Java 栈,成为当前方法帧。当调用结束(返回)时,就弹出该帧。
   编译器将源代码编译成字节码(.class)时, 就已经将各种类型的方法的局部变量, 操作数栈大小确定并放在字节码中,随着类一并装载入方法区。当调用方法时,通过访问方法区中的类的信息,得到局部变量以及操作数栈的大小。
   也就是说: 在方法中定义的一些基本类型的变量和对象的引用变量都在方法的栈内存中分配。 当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java 会自动释放掉为该变量所分配的内存空间, 该内存空间可以立即被另作它用。

  • 堆内存
       堆内存用来存放由 new 创建的对象和数组。在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。
       在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量, 让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。
       引用变量就相当于是为数组或对象起的一个名称, 以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

  • 本地方法栈内存
       与调用的本地方法的语言相关,如:调用的是一个c语言方法则为一个c栈。本地方法可以回调java方法。若有java方法调用本地方法,虚拟机就运行这个本地方法。
       在虚拟机看来运行这个本地方法就是执行这个java方法,如果本地方法抛出异常,虚拟机就认为是这个java方法抛出异常。
       Java通过Java本地接口JNI(Java Native Interface)来调用其它语言编写的程序,在Java里面用native修饰符来描述一个方法是本地方法。

下面通过一个简单的代码示例,理解Java中,内存是怎么进行分配与管理的。示例如下:
public class JavaRamExplain {  
    public static void main(String[] args) {  
        Person.whatCountry();  
          
        Person sam = new Person("sam", 20);  
        sam.introduceSelf();  
    }  
}  
class Person {  
  
    private String name;  
    private int age;  
    public static String country = "china";  
  
    public Person(String name, int age) {  
        this.name = name;  
        this.age = age;  
    }  
  
    public void introduceSelf() {  
        System.out.println("My name's " + name + ",i'm " + age + " years old.");  
    }  
  
    public static void whatCountry() {  
        System.out.println("This people come from " + country);  
    }  
} 

当开始运行JavaRamExplain类时,JVM便会开始进行内存的分配管理工作。

图解过程为:

图片较大,可右击查看原图

可以看到到第八步工作结束后:

  • 栈内存中的数据全部被释放(所以说栈内存中的数据的生命周期是已知并固定的,因为随着方法的执行结束,栈内存便会进行释放);
  • 堆内存中的Person对象,现已没有任何对象引用指向它,所以它将被视作内存中的“垃圾”,等待回收。(堆内存中的数据由java的垃圾回收机制自动进行处理,所以其生命周期不确定)

由图中也可以看到:

  • 类的方法会进行压栈和弹栈,对应的,方法中用到的参数(变量)便会相应的在栈内存中进行存储和释放。所以栈内存用于存放局部变量(包括基本类型和引用类型)。
  • 类的对象会被存放到堆内存中,相应的该对象所包含的成员变量也会被存放到该空间。
  • 类本身将在jvm通过.class运行该类时就会被加载到内存中的方法区内,顾名思义,方法区用于保存类的方法代码,其中普通方法被存放在非静态区,静态成员(方法和变量)被存放在方法区中专门的静态区当中。
  • 栈内存是方法的运行区域(因为方法中定义的局部变量需要在栈里开辟空间),方法区是方法的存放区域。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351