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

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

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

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

 package demo;

 public class Student {
private String name;
private int age; public void study() {
System.out.println("I love study!");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}
 package demo;

 public class StudentDemo {
public static void main(String[] args) {
Student student = new Student(); System.out.println(student.getName() + ":" + student.getAge());
student.setName("John");
student.setAge(23);
System.out.println(student.getName() + ":" + student.getAge()); student.study(); Student student2 = student;
student2.setName("Jack");
student2.setAge(25);
System.out.println(student2.getName() + ":" + student2.getAge());
System.out.println(student.getName() + ":" + student.getAge());
}
}

当我们运行程序时,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

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

Java程序内存的简单分析的更多相关文章

  1. Java 程序内存分析

    转自:http://www.iteye.com/topic/528230 java程序内存主要分为了2个部分,包括stack segment(栈内存区).heap segment(堆内存区). 在分析 ...

  2. 初识Java程序,编写简单代码?

    Dear All: 初识Java程序,编写简单代码? 首先小编在这里说下我们今天编写Java程序使用的是 eclipse 开发工具! 1.下载eclipse 官网地址:http://www.eclip ...

  3. 利用JConsole工具监控java程序内存和JVM

    一.找到java应用程序对应的进程PI 性能测试应用程序访问地址:http://192.168.29.218:7070/training/ 部署的应用服务器为tomcat6.028 启动tomcat服 ...

  4. (转)利用JConsole工具监控java程序内存和JVM

    转自:http://www.cnblogs.com/luihengk/p/5446279.html 一.找到java应用程序对应的进程PI 性能测试应用程序访问地址:http://192.168.29 ...

  5. java基础---->hashSet的简单分析(一)

    对于HashSet而言,它是基于HashMap实现的,底层采用HashMap来保存元素的.今天我们就简单的分析一下它的实现.人生,总会有不期而遇的温暖,和生生不息的希望. HashSet的简单分析 一 ...

  6. Java简单实验--关于课后提到的java重载函数的简单分析

    根据这一小段代码,获得了以下的测试截图: 简单分析:根据输出结果,判断这段代码用到了两个不同的函数方法,输出的不止有double类型的数,还有整型的数. 又根据类中的定义情况,square是根据判断传 ...

  7. Java程序内存分析:使用mat工具分析内存占用

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  8. linux下分析Java程序内存汇总

    使用pmap查看进程内存 执行命令 使用pmap能够查看某一个进程(非java的也能够)的内存使用使用情况, 命令格式: pmap 进程id 演示样例说明 比如执行: pmap 12358 显示结果例 ...

  9. Java程序内存分析

    1. Runtime.getRuntime().freeMemory() 和 jvisualvm.exe http://blog.csdn.net/u011004037/article/details ...

随机推荐

  1. js获取当前时间显示在页面上

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  2. 多线程 ThreadPool线程池

    简单说明一下: 线程池可以看做容纳线程的容器:一个应用程序最多只能有一个线程池:ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池: 每排入一个工作函数,就相 ...

  3. cordova编译报错:Execution failed for task ':processDebugResources'

    cordova编译报错:Execution failed for task ':processDebugResources' 引发这个错误的最扩祸首就是一个中文命名的文件,不知道什么时候加入的,我写了 ...

  4. PHP将富文本编辑后的内容,去除样式图片等只保留txt文本内容

    1.从数据库读取富文本内容样式如下: <p style=";text-indent: 0;padding: 0;line-height: 26px"><span ...

  5. Geometry Curve of OpenCascade BRep

    Geometry Curve of OpenCascade BRep eryar@163.com 摘要Abstract:几何曲线是参数表示的曲线 ,在边界表示中其数据存在于BRep_TEdge中,BR ...

  6. 一个在ASP.NET中利用服务器控件GridView实现数据增删改查的例子

    备注:这是我辅导的一个项目开发组的一个例子,用文章的方式分享出来,给更多的朋友参考.其实我们这几年的项目中,都不怎么使用服务器控件的形式了,而是更多的采用MVC这种开发模式.但是,如果项目的历史背景是 ...

  7. PHP将部分内容替换成星号

    在最近的项目中,会碰到到某人的手机号码隐藏中间几位,身份证号码只显示末尾4位的需求.当时一开始是网上搜索了一下,看到有人是用substr_replace这个函数来替换的,后面我也用了这个函数,但在用的 ...

  8. Elasticsearch聚合初探——metric篇

    Elasticsearch是一款提供检索以及相关度排序的开源框架,同时,也支持对存储的文档进行复杂的统计--聚合. 前言 ES中的聚合被分为两大类:Metric度量和bucket桶(原谅我英语差,找不 ...

  9. PHP 中的Closure

    PHP 中的Closure Closure,匿名函数,又称为Anonymous functions,是php5.3的时候引入的.匿名函数就是没有定义名字的函数.这点牢牢记住就能理解匿名函数的定义了. ...

  10. MVC中的默认Model绑定者DefaultModelBinder

    一.题外话 接续上一篇: MVC中Action参数绑定的过程 public IModelBinder DefaultBinder { get { if (this._defaultBinder == ...