zoukankan      html  css  js  c++  java
  • Java程序内存的简单分析

    http://www.cnblogs.com/huangminwen/p/5928315.html#undefined

    这篇文章将简单的说明下当我们运行Java程序时JVM(Java虚拟机)的内存分配情况。

    首先我们先来感观的认识下几个名词:

    1、栈,一般来说,基本数据类型直接在栈中分配空间,局部变量(在方法代码段中定义的变量)也在栈中直接分配空间,当局部变量所在方法执行完成之后该空间便立刻被JVM回收,还有一种是引用数据类型,即我们通常所说的需要用关键字new创建出来的对象所对应的引用也是在栈空间中,此时,JVM在栈空间中给对象引用分配了一个地址空间(相当于一个门牌号,通过这个门牌号就可以找到你家),在堆空间中给该引用的对象分配一个空间,栈空间中的地址引用指向了堆空间中的对象区(通过门牌号找住址);

    2、堆,一般用来存放用关键字new出来的数据。

    接下来我们再通过一段程序来直观感受下程序运行时JVM的内存情况,

    复制代码
     1 package demo;
     2 
     3 public class Student {
     4     private String name;
     5     private int age;
     6 
     7     public void study() {
     8         System.out.println("I love study!");
     9     }
    10 
    11     public String getName() {
    12         return name;
    13     }
    14 
    15     public void setName(String name) {
    16         this.name = name;
    17     }
    18 
    19     public int getAge() {
    20         return age;
    21     }
    22 
    23     public void setAge(int age) {
    24         this.age = age;
    25     }
    26 }
    复制代码
    复制代码
     1 package demo;
     2 
     3 public class StudentDemo {
     4     public static void main(String[] args) {
     5         Student student = new Student();
     6 
     7         System.out.println(student.getName() + ":" + student.getAge());
     8         student.setName("John");
     9         student.setAge(23);
    10         System.out.println(student.getName() + ":" + student.getAge());
    11         
    12         student.study();
    13         
    14         Student student2 = student;
    15         student2.setName("Jack");
    16         student2.setAge(25);
    17         System.out.println(student2.getName() + ":" + student2.getAge());
    18         System.out.println(student.getName() + ":" + student.getAge());
    19     }
    20 }
    复制代码

    当我们运行程序时,JVM会把Student类与StudentDemo类编译完然后加载到JVM中一个叫方法区的地方,类的成员变量与成员方法也被加载到方法区中,此时内存模型如下

    可以看到study方法右边各有一个16进制的标记,而name与age变量没有,这是因为每个对象都有各自的成员变量,而类中的成员方法却可以被每个对象所共用,为了节省内存空间,JVM为方法分配了该标记(也叫内存地址)便于每个new出来的对象查找调用,接着JVM会自动寻找main方法,在栈中为main方法申请一个空间,这个过程也叫入栈,然后执行我们Student类中第5行代码,这时候,JVM在堆空间中分配一块内存给Student对象,并为其分配一个内存地址(如果对象的成员变量没有赋值,则JVM会为变量赋初始值),在栈中分配一块内存空间用于指向堆空间中的Student对象区的内存地址,此时内存模型如下

    接着看代码第8行与第9行,程序为student对象的成员变量赋值,JVM会根据student所指向的地址在堆内存中寻找Student类的变量,并为变量赋新的值

    第12行,这时student对象调用study方法,JVM在栈空间中为study方法申请了一块内存空间

    study方法执行完后,立即释放栈空间,代码第14行,student2对象的引用指向了student所指向的地址

    代码15与16行,为student2的变量赋值,由于student2与student指向了同一个地方,所以这时student对象中变量的值也被改变

    到这,main方法中所有代码执行完毕,main方法所占用的栈空间也被回收,而堆空间等待GC回收

    代码执行结果如下:

    null:0
    John:23
    I love study!
    Jack:25
    Jack:25

    写的较为简单,仅作为知识记录,欢迎指正!

  • 相关阅读:
    背包问题--动态规划
    day03_13 多分支if语句及作业
    day03_12 缩进介绍
    day03_11 if语句实现猜年龄01
    day03_10 注释及简单的用户输入输出
    day03_09 编码部分历史及文件编码简介
    day03_07 变量的重新赋值01
    day03_06 变量详解
    day03_05 Python程序文件执行和与其他编程语言对比
    day03_04 文件后缀及系统环境变量
  • 原文地址:https://www.cnblogs.com/shoubianxingchen/p/6415847.html
Copyright © 2011-2022 走看看