博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
栈与堆的个人理解
阅读量:3943 次
发布时间:2019-05-24

本文共 3026 字,大约阅读时间需要 10 分钟。

文章目录

图解

将方法区放在堆上是为了便于理解,逻辑上方法区为堆的一部分

在这里插入图片描述

在这里插入图片描述

文字解析

1.jvm虚拟机启动,java堆创建,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都应当在堆上分配

2.将main方法栈帧压入栈,当java虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用的类是否已被加载,解析和初始化过,如果没有,那必须先执行类加载过程,:1.加载:编译类.java文件成.class文件(加载类元信息),2.链接(校验class文件正确性和安全性,生成方法表并分配元空间内存)
3.加载cat类的static变量跟static方法还有构造方法进入方法区.(类对象初始化:执行类变量赋值和静态代码块),此时新建类对象完毕。
4在栈上新建变量oldCat,bigCat,smallCat,并约束类型为Cat,新建变量Cats,约束类型为List,在堆上开辟内存地址,新建对象,通过同样的内存地址连接起来(实例对象加载的过程,1.对象实例化,在堆中分配内存 ,2.初始化零值,设置对象头,执行init方法,3.将引用指向内存空间,创建新Catclass对象完毕。)
5.调用cats.add(bigCat);时,去方法区寻找类的方法表,根据方法表找到内存地址中的add()方法,将此方法压入栈中(入栈),往对象cats中新增一个bigCat对象
6.cats.add(bigCat);运行结束,栈帧出栈销毁;
7.cats.add(smallCat);同上
8.调用oldCat.setName(“大猫”);时,将此方法压入栈中(入栈),将堆上0x001对象的name变量指向常量区"大猫"的内存地址(如果大猫在常量池中不存在,则会先在常量池里新增:大猫)
9.oldCat.setName(“大猫”);运行结束,栈帧出栈销毁
10.oldCat.setOld(10);
oldCat.setChild(cats); 同上
11.调用oldCat.say();时,将此方法压入栈中(入栈),在栈帧中生成局部变量:String food = “fish”;打印语句从常量池中获取"我的名字是".从堆对象中获取成员变量的name,将其组合打印出来(常量字符串的“+”操作,编译阶段直接会合成为一个字符串。如string str=”JA”+”VA”,在编译阶段会直接合并成语句String str=”JAVA”,于是会去常量池中查找是否存在”JAVA”,从而进行创建或引用。)
(string对象的创建讲解: https://blog.csdn.net/tyyking/article/details/82496901)
12.将hello方法压入栈中,hello是static方法,直接调用方法区已经变异的代码缓存,调用结束,出栈
13.main方法执行完毕,出栈

完整代码

/** * @author Boss * 编写一个类时没有添加无参构造方法,那么编译器会自动添加无参构造方法;(如果自己添加构造函数,无论有参数或是没参数,默认构造函数都将无效) * 编写时添加了有参构造方法而未添加无参构造方法,那么编译器只认有参构造方法而不会默认添加无参构造方法! * 如果需要使用无参构造方法,一定要在类里面添加 */public class Cat {
//(成员变量)静态变量 成员变量是属于类的,存在于堆上的方法区,"白色"存在于字符串常量池 static String colore = "白色"; //(成员变量)如果没有使用static修饰,这个成员变量是属于实例的,存在堆上 private String name; private Integer old; private List
child; public Cat() {
} public Cat(String name, Integer old) {
this.name = name; this.old = old; } public Cat(String name, Integer old, List
child) {
this.name = name; this.old = old; this.child = child; } public String getName() {
return name; } public void setName(String name) {
this.name = name; } public Integer getOld() {
return old; } public void setOld(Integer old) {
this.old = old; } public List
getChild() {
return child; } public void setChild(List
child) {
this.child = child; } public static void hello(){
System.out.println("你好你好你好你好你好"); } public void say() {
//局部变量 String food = "fish"; System.out.println("我的名字是" + this.name); System.out.println("我的食物是" + food); System.out.println("我的颜色是" + colore); } public static void main(String[] args) {
Cat oldCat = new Cat(); Cat bigCat = new Cat(); Cat smallCat = new Cat(); List
cats = new ArrayList<>(); cats.add(bigCat); cats.add(smallCat); oldCat.setName("大猫"); oldCat.setOld(10); oldCat.setChild(cats); oldCat.say(); Cat.hello(); }}

结果

在这里插入图片描述

jdk1.8图解jvm

在这里插入图片描述

你可能感兴趣的文章
字符串列表的C语言实现:c_strlist
查看>>
客户沟通的方式:礼貌待客沟通方式,技巧推广沟通方式,个性服务沟通方式
查看>>
用弹性工作制留住员工
查看>>
知识=经验×反思2
查看>>
领导者如何发现关键问题
查看>>
学习无为领导力
查看>>
卓越领导看过程
查看>>
领导力与各种循环挑战
查看>>
达成谈判协议 - 避免操之过急
查看>>
销售人说话“十大忌”
查看>>
营销中的“战略非对称”
查看>>
android 如何开关Mediatek开发的Feature
查看>>
Android电话功能各部分深入探讨
查看>>
Android应用技巧总结
查看>>
Android创建sdcard详细图解
查看>>
Android开发:如何实现TCP和UDP传输
查看>>
Android电源管理相关应用技巧分享
查看>>
Android录音失真具体解决方案
查看>>
Android根文件系统相关应用介绍
查看>>
Android文件系统深入剖析
查看>>