java内存初探(二)

呃,昨天吃完饭血液大多涌向了胃部,然后我的脑子闹脾气了:明明晚上还要我干活,结果不给我充足的血液怎么行呢?所以它罢工了,那我也没有办法,只能今天再写这一篇了哈哈哈。
很巧妙的掩饰了自己昨天的懒惰之后,我们话不多说,继续继续。

昨天说到classloader将字节码文件加载到jvm的时候有三个阶段,分别是装载、连接和初始化三个过程。下面我就来分别聊聊这三个阶段(昨天抄的博客和今天抄的内容居然冲突了,可恶,我还得再去看看哪个是对的)

1.装载
装载的主要过程是先将.class的信息读取到内存中来,首先通过类的全限定名读取到描述此类的二进制流,这个全限定名我的理解是包名加类名,大致是这种形式的:com.mysql.jdbc.Driver,然后这个字节流所代表的静态存储结构转化为方法区的运行时结构,然后在堆中生成一个这个类的java.lang.Class对象,作为方法区数据的访问入口,这个对象呢,不是String s=new String();这种对象,s是一个对象,但它是String类的,而我们刚才生成的对象是 Class c=s.getClass();这种,这个对象的类是class,而且对于每一个类来说,它在堆中的class对象都只有一个。

2.连接
连接分为三个部分,分别是验证,准备和解析
昨天好像说到,运行一个类之前我们起码得先看看这东西是不是坏的吧,要不然给我机子跑坏了那可就不好了,所以呢,当装载完毕之后,第一时间就要检查字节信息是否符合jvm的规范,这些规范包括文件格式、元数据、字节码和符号引用的验证。(你看懂上面的规范了吗?我反正没看懂,全是抄的哈哈哈。)

接下来是准备阶段,准备阶段是正式为类变量分配内存并为类变量设定初始值的阶段,静态变量赋予默认值(int a=0,object o=null,你赋予的值不算),常量赋予初始值(就是你给这个常量赋予的值)

然后是解析阶段,我们刚才用的是全限定名来引用一个类,比如:com.mysql.jdbc.Driver,但是现在我们已经将这个类的class对象创建出来了,所以直接用堆中这个类的实际地址就可以了。

3.初始化
初始化阶段主要干的是初始化静态块的内容,并对静态变量进行真正的赋值操作,这里jvm会执行编译器自动生成的()方法,这个()干了些啥呢,简单来说就是搜集了类中static{}静态块组成的代码(没有构造器的代码!!!前面有篇博客坑我),然后挨个执行下去就行了。这个阶段我有点疑惑啊,既然你说执行的是静态代码块的东西,那public static a=10;这个你是执行还是不执行呢?这个算静态代码块吗?后来上网上再查了一下,这语句也运行,那这个初始化基本上所有的静态变量就都拥有了自己的初始值了。这里还有再强调一点,如果这个类还有父类,那么首先要先把它的父类也给加载进来,流程一样

装载完之后终于到了执行代码的阶段了,运行个程序可真累,如果需要一个对象,那么我们需要调用它的构造函数,也就是init方法,生产出一个对象放入堆中。

累了累了,不写了,剩下的晚上再写,我发誓晚上必写!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值