java静态类堆栈_JAVA堆栈

最近在看JAVA虚拟机规范,谈下自己对java堆栈的理解

java虚拟机内存分为:栈、本地方法栈、堆、程序计数器、方法区

JAVA栈

java栈中的运行单位是栈帧。

class ActivityThread {

public void main() {

int index = 0;

Student student = new Student();

}

}

上面一段代码很简单,讲下其运行过程:

1:java虚拟机查找方法区中是否已经加载了ActivityThread的字节码信息,如果没有,则加载其字节码并保存到方法区。将静态成员变量保存到方法区的静态存储区(此时会完成静态成员变量的初始化,只有一次初始化);将常量保存到常量池中;多态的动态链接也发生在这一步

2:确定堆区域要调用的main()方法,然后java虚拟机会到方法区中找到main方法的字节码,生成对应的栈帧,压栈运行。

PS:第二步栈帧也是要占内存的,其内存大小在创建栈帧时就已经确定,并且在运行过程中不会发生变化。原因就是栈帧中有一个局部变量表,其中的所有类型并且所占空间在编译时都已经确定。虚拟机将所有数据类型定义为u1类型,long和double定义为u2类型,u1占4个字节,u2占8个字节,都是以u1和u2为单位操作的。

3:index和值0,会被存放到栈帧的局部变量表中。执行Student student = new Student();这一行时,如果方法区没有Student信息,java虚拟机加载Student。student是对象的别名,存放的是new Student()对象在堆中的起始地址

4:方法运行结束,销毁栈帧

5:栈和程序计数器都是线程独立的,即每个线程都有自己的栈和程序计数器

6:栈大小包括指定栈深度和动态申请两种,分别可能发生栈溢出或者OOM

JAVA堆

堆是用来存储对象的。有很多很多种垃圾回收器,前面有篇博客介绍了JAVA对象的创建和回收,这里就不在多说。

对象销毁

一个对象的销毁要经过两次标记,第一次标记:GC ROOT不能到达时会把对象标记为死对象,然后将该对象放入F-Queue列,java虚拟机会创建线程单独处理F-Queue中的对象,此时会调用对象的finalize()方法,在此方法中,可以将该对象复制给其他引用,这样就可以把该对象再次加入引用链。第二次标记:如果在后续的GC过程中,如果GC ROOT再次不能到达此对象,对象会被第二次标记为死对象,然后直接回收掉。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值