Java自学随笔 - 创建对象使用时的内存分析随笔1

对象通过类中自带的构造方法类创建(此处不详细展开)
那么在创建对象的过程中,对象去访问成员变量,jvm又发生了哪些变化呢?
此处通过代码和画图的形式来详解
code图:
代码
实际完整code:

class husband{
    String name;
    wife w;
}
class wife{
    String name;
    husband h;
}
public class Demo10 {
    public static void main(String []args){
        husband huangxiaoming = new husband();
        huangxiaoming.name = "黄晓明";
        wife yangying = new wife();
        yangying.name = "杨颖";
        huangxiaoming.w = yangying;
        yangying.h = huangxiaoming;
        System.out.println(huangxiaoming.name + "的妻子的名字: " + huangxiaoming.w.name);

    }
}

接下来我们逐行代码分析,jvm中的内存变化过程
step 1:
创建了一个公共类,且这个类名和java文件名一致,那就是主类在这里插入图片描述 在这里插入图片描述
step 2:
创建了两个类,一个husband类,一个wife类。
在这里插入图片描述
那么此时的jvm的内存结构是什么样的呢?
在这里插入图片描述
step 3:
创建了两个对象,并对各自类中的实例变量name进行初始化赋值

husband huangxiaoming = new husband();
huangxiaoming.name = "黄晓明";
wife yangying = new wife();
yangying.name = "杨颖";

此时的jvm内存图为:
在这里插入图片描述
step 5:

huangxiaoming.w = yangying;

上述代码,yangying这个变量储存的内存地址赋给了huangxiaoming这个引用实际指向的husband对象中的w,也就意味着此时的实例变量w是指向yangying的实际对象

yangying.h = huangxiaoming;

上述代码,栈中huangxiaoming变量所存储的所指对象内存地址,赋给了yangying的实际对象中的对象变量h,那么此时也就是说,对象变量h中的内存地址和huangxiaoming中是一样的。
那么我们发现了一个有趣的地方如图:
在这里插入图片描述
huangxiaoming和yangying他们的实际对象中的w,h的内存地址各自指向对方在堆内存中的内存地址,所以也就是说,通过这样的内存地址交换,使得我只需要创建一个对象,我这个对象下的对象变量还会去指向其他对象中的对象变量,一环套一环,使得对象之间可以联系起来。
比如,我想要输出:黄晓明的老婆的名字叫什么

 System.out.println(huangxiaoming.name + "的妻子的名字: " + yangying.name);

这么写可以么?当然可以,也没错。但是我们需要弄清楚一个需求:黄晓明的老婆的名字?
黄晓明的老婆是何种关系?是从属关系,也可以理解为黄晓明是主目录,而老婆是子目录,子目录属于主目录。上述yangying.name这个打印出来的,和黄晓明没有关系。
那也就是说不同对象之间是可以通过各自的实例变量使用step5的方式联系起来,这样使得输出的数据更有逻辑性和合理性。如果还没有明白,下面这个图可以更为直观的描述,为什么不能直接用
**System.out.println(huangxiaoming.name + “的妻子的名字: " + yangying.name);**来输出结果?举一个不恰当的例子,如下
这里有部电影,电影是《我的二战》(名字我瞎编的),电影记录了主人公经历了抗日战争,中途岛战役,诺曼底登录这三个阶段中战斗的故事,并且每个章节的结尾,都会用同一句话来结尾:“终于打赢了”。且会使用不同状语去修饰喊出这句话的时候的一个状态。
在这里插入图片描述
从开始的悲愤,到最后的兴高采烈,都体现了主人公在每个章节结尾处的心态变化。那么如果用代码的思想来考虑下:
我要打印我在最后一个章节,说出的那句结尾的话,那么就有:
System.out.println(我.第三章.兴高采烈.结束语);
那么我们比较一下:
System.out.println(我.第一章.悲愤.结束语);
System.out.println(我.第二章.艰难.结束语);
System.out.println(我.第三章.兴高采烈.结束语);
虽然最终打印出来的都是"终于打赢了”,但是实际上话语中的心理变化是不一样的,所以这三句"终于打赢了"并不相同。

总结

1.jvm(java虚拟机)主要包括三块内存空间,分别是:栈内存,堆内存,方法区内存。
2.堆内存和方法区内存各有一个,一个县城一个栈内存。
3.方法调用的时候,该方法所需要的内存空间在栈内存中分配,被称为压栈。方法执行结束之后,该方法所属的内存空间释放,称为弹栈。
4.栈中主要储存的是方法体当中的局部变量。
5.方法的代码片段以及整个类的代码片段都被存储到方法区内存当中,在类加载的时候,这些代码片段会载入。
6.在程序执行过程中使用new运算符创建的java对象,存储在堆内存当中。
7.变量分类
- 局部变量【方法体重声明】
- 成员变量【方法体外声明】
* 实例变量【前边修饰符没有static】
* 静态变量【前边修饰中有static】
8.静态变量存储在方法区内存当中。
9.三块内存中变化最频繁的是栈内存,最先有数据的是方法区内存,垃圾回收器主要是针对的是堆内存。
10.当垃圾回收器【自动垃圾回收机制,GC机制】什么时候回考虑将某个java对象的内存回收呢?
* 当堆内存当中的java对象成为垃圾数据的时候,会被垃圾回收器回收
* 什么时候堆内存中的java对象会变成垃圾呢?
没有更多的引用指向它的时候。
这个对象无法被访问,因为访问对象只能通过引用的方式访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值