从JVM角度分析Java程序对内存空间的使用?
2017-09-01 本文已影响53人
编程界的小学生
一、JVM内存模型大致分为三大部分

我知道还有程序计数器,栈还分为本地方法栈和虚拟机栈,此处不多讲解
二、一个HelloJVM带你读懂是怎么运行的?
package jvm.day02;
/**
* 从JVM调用的角度分析Java程序对内存空间的使用
*
* 当JVM进程启动的时候,会从类加载路径中找到包含main方法的入口类HelloJVM
* 找到HelloJVM后会直接读取该文件中的二进制数据并且把该类的信息放到方法区
* 然后会定位到HelloJVM中的main方法的字节码并开始执行main方法中的指令
*
* Student student = new Student("java");
* 此时会创建Student实例对象并且使用student来引用该对象(或者说对该对象命名),其内幕如下:
* 第一步:JVM会直接到方法区中查找Student类的信息,此时发现没有Student类,就通过类加载器加载该Student类文件
* 第二步:在JVM的方法区加载并找到了Student类之后会在Heap区中为Student实例对象分配内存
* 并且在Student的实例对象中持有指向方法区中的Student类的引用(内存地址);
* 第三步:JVM实例完后会在当前线程中为Stack中的reference建立实际的引用关系,此时会赋值给student
*
* 在JVM中方法的调用一定是属于线程的行为,也就是说方法调用本身会发生在调用线程的方法调用栈:
* 线程的方法调用栈(Method Stack Frames),每一个方法的调用就是方法调用栈中的一个Frame,
* 该Frame包含了方法的参数、局部变量、临时数据等。
* student.sayHello();
*
* @author TongWei.Chen 2017-09-01 16:51:41
*/
public class HelloJVM {
/**
* 在JVM运行的时候,会通过反射的方式到Method区域找到入口类的入口方法main
* @param args
*/
//main方法也是放在方法区域的
public static void main(String[] args) {
/**
* student是存放在主线程的Stack中的;
* Student对象实例是放在所有线程共享的Heap区域中的
*/
Student student = new Student("java");
/**
* 指针和句柄的粗略区别:
* 指针:直接指向对象
* 句柄:先指向句柄,句柄在指向对象
*
* 首先会通过student指针(非句柄)找到Student对象,
* 当找到该对象后会通过对象内部指向方法区中的指针来调用具体的方法去执行任务
*/
student.sayHello();
}
}
class Student {
//name本身作为成员是放在Stack中的,但是name指向的String对象是在Heap中的
private String name;
public Student(String name) {
this.name = name;
}
//sayHello这个方法是放在方法区域中的
public void sayHello() {
System.out.println("Hello, this is " + this.name);
}
}
三、真的很清晰明了了,实在不懂请留言或私信或进群问我。
若有兴趣,欢迎来加入群,【Java初学者学习交流群】:458430385,此群有Java开发人员、UI设计人员和前端工程师。有问必答,共同探讨学习,一起进步!
欢迎关注我的微信公众号【Java码农社区】,会定时推送各种干货:
