Java面向对象进阶之简单内存分析

前言

如果没有面向对象基础,先看一个Java类看懂面向对象.

当new对象时,才会涉及到内存的分配,此时构造器构造对象的静态特征和动态行为。
JVM内存分为函数栈、堆、方法区。

一、内存分析

package com.xhu.java;

import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 一群学生抽象出来的学生类,抽象就是一个向上找描述物体的框架过程。
 */
public class Student {
    /**
     * 第一部分,一群物体抽象出来的静态特征,它们的公共特征。对一群物体观察得越仔细,抽象出来的静态特征越多。
     */

    public String idCard;//每个学生都有身份证号码
    public String name;//每个学生都有姓名
    public Date birth;//每个学生都有出生时间

    /**
     * 第二部分,一群物体抽象出来的动态行为,它们的公共行为。对一群物体观察得越仔细,抽象出来的动态行为越多。
     */

    public void eat() {//每个学生都有吃饭的行为。
        //面向过程去编写吃饭这个行为。
        System.out.println("洗手");
        System.out.println("吃饭");
        System.out.println("洗碗");
    }

    public void sleep() {//每个学生都有睡觉的行为。
        //面向过程去编写睡觉这个行为。
        System.out.println("洗漱");
        System.out.println("上床");
        System.out.println("睡觉");
    }

    /**
     * 这是动态行为跟静态特征关联协作的地方。
     */
    public void updateName(String name) {//每个学生可以修改他的名字
        this.name = name;
    }

    /**
     * 第三部分,构造器,向上的过程为抽象,向下的过程就是具体。比如来了一个新同学,一个真实的学生,此时就需要把他实例构造出来。
     */
    public Student(String idCard, String name, Date birth) {//构造一个真实的对象,对他的基本特征设定一个具体的值
        this.idCard = idCard;
        this.name = name;
        this.birth = birth;
    }
    /*public Student Student(){
        return this;
    }*/
    /**
     * 实例化对象,Java要求所有函数写入类之中,写一个该类的入口函数(该函数属于类,所以应该是static)main函数。(run一个类,必须要有入口函数main)
     */
    public static void main(String[] args) {
        //通过new构造器来向下构造一个具体的对象
        Student s1 = new Student("111111111111","Jack马", new GregorianCalendar().getTime());
        Student s2 = new Student("222222222222","Pony马",new GregorianCalendar().getTime());
    }
}

1)进入主函数,开辟一个栈帧,有自己的变量
在这里插入图片描述
注:这里的参数有默认赋值,不同类型有不同的默认方式
在这里插入图片描述
所以此时args = null;s1 = null;s2 = null.

2)Student s1 = new Student("111111111111","Jack马", new GregorianCalendar().getTime());,此时要new出对象s1,调用构造函数,开辟栈帧,开辟对象空间并赋值。
在这里插入图片描述

3)执行Student s2 = new Student("222222222222","Pony马",new GregorianCalendar().getTime());,前一个构造函数结束,栈顶帧出栈,调用新的构造器开辟新的栈帧。
在这里插入图片描述

4)调用构造函数完毕,出栈。此时,买main函数也调用完毕,main函数出栈,程序结束。

总结

1)JVM的函数栈、堆、方法区。
2)面向对象时的简单内存分析。

参考文献

[1] 尚硅谷Java SE–高淇

附录

1、JVM内存模型介绍

在这里插入图片描述
1)对于每一个线程,都有
a)程序计数器,记录程序运行到那一步,当中断结束后,能从该地方继续执行。
b)虚拟机栈,也称函数执行栈,main函数打底,调一个函数就将开辟栈帧,即进栈;调用结束就出栈。栈帧里面存有局部变量表,编译时期可知基本数据类型、对象引用、方法出口。
c)本地方法栈,对于系统调用函数的函数栈。
注:这三个属于线程私有,不共享。
2)对于堆,创建的对象,直接分配在堆上。(只有一个堆)堆被所有的线程共享。为了便于快速垃圾回收,将堆划分为新生代和老年代。
3)对于方法区,本质也是堆,不连续存储,被所有线程共享。存储一些类信息、常量、静态变量、即时编译后的代码等数据(不变的信息)。
注:方法区是一种规范,而不同版本的JDK实现不同。
JDK7以前:方法区就是堆中的“永久代”。
JDK7,部分去“永久代”,把静态变量、字符串常量移到了堆内存中。
JDK8,“永久代”不存在了,类信息、编译后的代码信息和数据存到直接内存上,即本地内存上。不在堆内层上。

  1. 运行常量池,存字面量、如文本字符串、final常量;存符号引用,即与编译相关的常量。
  2. 直接内存,直接内存并不属于Java规范规定的属于Java虚拟机运行时数据区的一部分。Java 的NIO可以使用Native方法直接在java堆外分配内存,使用DirectByteBuffer对象作为这个堆外内存的引用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值