Java程序内存的简单分析

这篇文章将简单的说明下当我们运行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

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

时间: 2024-08-04 12:30:35

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

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

在工作中可能会遇到内存溢出这种灾难性的问题,那么程序肯定是存在问题,找出问题至关重要,上一篇文章讲了jmap命令的使用方法,当然用jmap导出的文件我们也看不懂啊,那就交给memory analyzer(mat)这个工具,让他帮助我们来观察程序的内存分布情况吧. 1. 用jmap生成堆信息 2. 将堆信息导入到mat中分析 3. 生成分析报告 Histogram Dominator Tree Top consumers Leak Suspects MAT 不是一个万能工具,它并不能处理所有类型的

Java 程序内存分析

转自:http://www.iteye.com/topic/528230 java程序内存主要分为了2个部分,包括stack segment(栈内存区).heap segment(堆内存区). 在分析Java程序内存分配情况时,我们从下面这个经常被使用的例子开始吧. 下面程序将打印什么呢? String s1 = new String("abc"); String s2 = new String("abc"); System.out.print(s1.equals(

c/c++服务器程序内存泄露问题分析及解决

由 www.169it.com 搜集整理 对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题.已经有许多技术被研究出来以应对这个问题,比如 Smart Pointer,Garbage Collection等.Smart Pointer技术比较成熟,STL中已经包含支持Smart Pointer的class,但是它的使用似乎并不广泛,而且它也不能解决所有的问题:Garbage Collection技术在Java中已经比较成熟,但是在c/c++领域的发展并不顺畅,虽然很早就有人思考

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

转自:http://www.cnblogs.com/luihengk/p/5446279.html 一.找到java应用程序对应的进程PI 性能测试应用程序访问地址:http://192.168.29.218:7070/training/ 部署的应用服务器为tomcat6.028 启动tomcat服务器后,任务管理器里可以看到多了java.exe进程,如图 PS:这里启动了多个其他程序 2.查询测试应用程序对应的进程PID号(根据端口号查找) 1)  Cmd命令:netstat  -aon|fi

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

对于HashSet而言,它是基于HashMap实现的,底层采用HashMap来保存元素的.今天我们就简单的分析一下它的实现. HashSet的简单分析 一.hashSet的成员变量组成 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable private transient HashMap<E,Object> map;

java程序中sql注入分析及优化方案

先来看看百度百科的解释: 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句.比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到sql注入攻击. 1.java程序

linux下分析Java程序内存汇总

使用pmap查看进程内存 执行命令 使用pmap能够查看某一个进程(非java的也能够)的内存使用使用情况, 命令格式: pmap 进程id 演示样例说明 比如执行: pmap 12358 显示结果例如以下图(内容较多, 分成几张图说明): 内容開始部分 内容结束部分 上图中, 第一列.内存块起始地址 第二列.占用内存大小 第三列,内存权限 第四列.内存名称.anon表示动态分配的内存,stack表示栈内存 最后一行.占用内存总大小,请注意,此处为虚拟内存大小,占用的物理内存大小能够通过top查

Java程序内存分析

1. Runtime.getRuntime().freeMemory() 和 jvisualvm.exe http://blog.csdn.net/u011004037/article/details/45740673 2.jmap命令 http://www.cnblogs.com/o-andy-o/archive/2013/06/11/3132335.html 3.mat工具 http://www.open-open.com/lib/view/open1404350384858.html

记一次java程序内存溢出问题

一个自然语言处理程序,在封装为web-service后,部署到线上运行. 但最近出现了内存溢出的情况,频繁的out of memory. 先盲目尝试在启动脚本中增加-XX:-UseGCOverheadLimit. 因为根据原因未找到,依然频繁的out of memory,只能一直观察jstat -gcutil <pid>,看到老生代内存降不下来时,重启程序. 服务程序很简单,简单接收参数,自然语言处理,返回数据,除了自然语言处理模块,都是方法参数,不会出现内存泄漏的情况. 第一次解决这种内存溢