1 java内存结构概述
java内存结构图如下
class文件->运行时数据区->jni
运行时数据区
栈区
虚拟机栈
特征:线程私有,生命周期与线程相同,使用连续的内存空间
作用:Java 方法执行的内存模型,存储局部变量表、操作栈、动态链接、方法出口等信息
本地方法栈
程序计数器
特征:占用内存小,线程私有,生命周期与线程相同
作用:大致为字节码行号指示器
方法区
特征:线程共享,生命周期与虚拟机相同,可以不使用连续的内存地址,是一个概念,不同的java版本有不同的实现,如永久代和元空间
作用:存储运行时常量池+静态变量+常量+字段+方法字节码+在类/实例/接口初始化用到的特殊方法等
堆区
新生代
伊甸区
from区
to区
老年代
永久代(java7及之前)
方法区的实现,逻辑上属于堆,实际上属于堆外内存,使用的是jvm内存
元空间(java8及之后)
方法区的实现,逻辑上属于堆,实际上属于堆外内存。元空间并不在虚拟机中,而是使用本地内存
2 案例分析
2.1 对象、属性内存分析
// 学生类:
public class Student {
//静态的数据
String name;
int id; //学号
int age;
String gender;
int weight;
Computer computer;
//动态的行为
public void study(){
System.out.println(name+"在學習");
}
public void sayHello(String sname){
System.out.println(name+"向"+sname+"說:你好!");
}
}
// 电脑类:
public class Computer {
String brand;
int cpuSpeed;
}
主程序:
Student s1 = new Student();
s1.name = "高琪";
s1.age = 18;
Computer c = new Computer();
c.brand = "联想";
c.cpuSpeed = 100;
s1.computer = c;
内存分析:
2.2 多态内存分析
多态构成的三个条件:继承、重写父类非静态方法、父类指针指向子类对象。
class HttpServlet{
public void service(){
doGet();
}
public void doGet(){
System.out.println("HttpServlet.doGet");
}
public static void getInstance(){
System.out.println("获取HttpServlet实例");
}
public static void init(){
System.out.println("初始化配置");
}
}
class MyHttpServlet extends HttpServlet{
@Override
public void doGet() {
System.out.println("MyHttpServlet.doGet");
}
public void doPost(){
System.out.println("MyHttpServlet.doPost");
}
public static void getInstance(){
System.out.println("获取MyHttpServlet实例");
}
}
说明:
每个方法都有两个隐式参数,this、supper。this指向创建的对象,supper指向父类对象。由于编译器问题,父类指针引用子类对象,调用方法的时候只能调用父类中存在的方法;如果子类有覆盖,则调用覆盖后的方法。
测试代码:
HttpServlet servlet1 = new HttpServlet();
servlet1.service();//HttpServlet.doGet
HttpServlet servlet2 = new MyHttpServlet();
servlet2.service();//MyHttpServlet.doGet
//servlet2.doPost();//报错
静态方法是属于某一个类的,子类不能重写父类的静态方法,子类与父类静态方法相同的时候不能构成重写,两个方法没有任何关系,如果子类方法加Override注解则报错。但是子类能继承父类的静态方法。调用的时候不传递this、supper隐式参数。
测试代码:
HttpServlet.getInstance();//获取HttpServlet实例
MyHttpServlet.getInstance();//获取MyHttpServlet实例
//子类调用父类的静态方法
MyHttpServlet.init();//初始化配置