近段时间研究了 java 的程序执行过程中的内存分配,收获颇多,解决了我最近时间学习 java 的很多困惑点。写 java 内存分析系列的目的主要有两个,一来是希望给像我一样的 java 初学者一定的启发,希望也能解决的 java 关于内存方面的困惑点。二来也是给自己做个总结,毕竟只有自己亲自写出来的东西,才是真正的东西。今天就开始 java 程序执行过程内存分析系列第一篇。
一般来说,作为初学者,一般只是将 java 程序的内存只是分为栈区,和堆区。确实刚开始学时这样划分能都便于我们理解,但是随着学习 java 时间的增多,如果内存划分还只是简单的只有栈和堆两个区,就有很多东西不能深入理解,就拿个常用的字符来说,就很难理解字符串的一些特性。于是乎我这里就增加一个内存区域的划分,这样比以前能理解更多的东西。这个新增的内存区域是什么呢?其实也不是新增,就是把以前堆内存划分为方法区和其他区。那方法区里面存放些什么东西勒, 方法区里面主要存放三个东西,第一个是程序的代码,第二个是常量池, 这里主要存放一些 java 程序中的一些常量和字符串常量,第三个是静态的变量。堆内存划分如图所示。
首先我定义了一个 people 类,里面有姓名和性别两个成员变量和一个说话的成员方法。另外还有一个测试类,测试 people 类,好了,万事俱备,只欠东风了。下面正式开始内存分析。
- 1 public class People {
- 2 String name; //定义一个人的姓名
- 3 String sex;
- 4 public void speak() {
- 5 System.out.println("hi 你好");
- 6
- }
- 7 8
- }
- 1 public class Test {
- 2 public static void main(String[] args) {
- 3 People p = new People();
- 4 System.out.println(p.name);
- 5 System.out.println(p.sex);
- 6 p.speak();
- 7
- }
- 8
- }
在程序开始运行时,执行的命令是 java Test(eclipse 刚开始也是要执行这句命令, 就是在执行运行的命令时,就是在执行 java Test), 这时 jvm 也就是 java 虚拟机会把 Test 类加载到方法区,然后找到程序的 test 类的里面的 main 方法,作为整个程序的入口,开始运行整个程序。首先执行第三行命令 people 怕 = new people();执行这行代码时,内存中发生了到底哪些变化,当 jvm 遇到 people p 首先会执行 jvm 会到他管理路径下面找 people 类,如果没找到,就会报错,如果找到就会把 people 类加载到方法区,前面提过方法区里面主要存放一些代码和一些常量,然后栈内存中保存 p 引用变量,并初始化为 null,加载完 people 类之后紧接着就执行 new people(),jvm 遇到 new 关键字到堆内存开辟一块空间,保存 people 类实例化的对象。并把这块内存的首地址赋值给 p。具体如图所示。
这里 p 引用的值是 new people()对象的内存空间首地址。这里需要注意的是成员变量有个初始值,所有引用类型的初始值是为 null,另外一个类创建的多个对象共享成员方法。
分析到这里,内存分析系列一就到这里了,接下来我会继续深入内存分析,关于 this,super 以及 static,string,和继承的内存分析,希望能对大家有所帮助。
来源: http://www.cnblogs.com/songadai/p/7092161.html