java的内存分析_Java程序内存的简单分析

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

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

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

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

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

1 packagedemo;2

3 public classStudent {4 privateString name;5 private intage;6

7 public voidstudy() {8 System.out.println("I love study!");9 }10

11 publicString getName() {12 returnname;13 }14

15 public voidsetName(String name) {16 this.name =name;17 }18

19 public intgetAge() {20 returnage;21 }22

23 public void setAge(intage) {24 this.age =age;25 }26 }

1 packagedemo;2

3 public classStudentDemo {4 public static voidmain(String[] args) {5 Student student = newStudent();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中一个叫方法区的地方,类的成员变量与成员方法也被加载到方法区中,此时内存模型如下

09eec9f29df8c417849cc63206043fad.png

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

15586e7a12fe5c15deef2d68d5a32add.png

这时候,JVM在堆空间中分配一块内存给Student对象,并为其分配一个内存地址(如果对象的成员变量没有赋值,则JVM会为变量赋初始值),在栈中分配一块内存空间用于指向堆空间中的Student对象区的内存地址,此时内存模型如下

f67030e7299f77b000661e18058cbe0b.png

接着看代码第8行与第9行

c5d88a717451e915175742e6ea56eb95.png

程序为student对象的成员变量赋值,JVM会根据student所指向的地址在堆内存中寻找Student类的变量,并为变量赋新的值

a8a7cd1e0cf1798b38a03c809a05290a.png

第12行

00b6f84d4eeebcb8e81754bb930788a4.png

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

a5bc2376629eeefafe0827c9a3cfc651.png

study方法执行完后,立即释放栈空间,代码第14行,

cb9d040e9e2b0c1ef9eae8a176a99311.png

student2对象的引用指向了student所指向的地址

fadd734b151ed4fd108c5fa51d35433f.png

代码15与16行

b7ae21ed189232f7987fbf26336f17be.png

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

487311ead6ab03ba8020bfc870783f30.png

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

8ae991fcfe48a4edf17038bf2e79c9ec.png

代码执行结果如下:

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值