上一篇内存分析问了一个问题:我们平常调用函数的时候究竟是怎样调用的呢?
既然对象只保存了成员变量,那么类的方法究竟装在那里呢?
还有又是如何调用呢?
在黑马的视频中就有讲述到这个情况。
----------------------------------------------------------------------------------------------------------------
其实java在内存中还有一个方法区,这里主要存储的是方法,静态成员,常量。
方法区中给每个类都规定了空间并且持有this和super的引用。
当运行到哪个对象的时候,通过this动态指向该对象,引用该对象的成员变量,
然后和方法以及局部变量一起在栈中进行运算。
而静态的变量和方法则不同,是直接存在到方法区,不需要this进行动态绑定,那样的情况叫做静态绑定
在类装载到方法区的时候,直接使用person.变量和方法就可以访问了,不需要持有对象的引用。
----------------------------------------------------------------------------------------------------------------
对于常量池
在String类中介绍了简要的讲解:
String s1 = "abc";//s1是一个类类型变量, "abc"是一个对象。 //字符串最大特点:一旦被初始化就不可以被改变。 String s2 = new String("abc"); //s1和s2有什么区别? //s1在内存中有一个对象。 //s2在内存中有两个对象。
以上为什么会有这种区别呢?
其实"abc" 这样的数据会找寻java中的常量池的数组是否有存在abc这样的字符,如果有就直接组合成新的字符串,如果没有则是将abc加入到常量池数组中,那么在new对象的时候就会有两对象,其实,new的对象是在堆中,而“abc”是在常量池中,堆中对象持有常量池的字符引用而已。
----------------------------------------------------------------------------------------------------------------
其实光是以上的资料,其实还是有很多疑问
第一:常量池在哪里?是java定义的一个新的空间吗?
第二:方法区里面详细构造没有给出
所以就会产生越来越多的疑问:
在找寻的相关资料后,总结了一下。
1,常量池(方法区中的一个数据结构)
常量池中保存中所有类型是用的有序的常量集合,包含直接常量(literals)如字符串、整数、浮点数的常量,和对类型、字段、方法的符号引用。常量池 中每一个保存的常量都有一个索引,就像数组中的字段一样。因为常量池中保存中所有类型使用到的类型、字段、方法的字符引用,所以它也是动态连接的主要对象。
2,方法区:
每一个被加载的类型,在Java虚拟机中都会在方法区中保存如下信息: 1)、类型的全名 2)、类型的父类型的全名(除非没有父类型,或者弗雷形式java.lang.Object) 3)、给类型是一个类还是接口 4)、类型的修饰符(public,private,protected,static,final,volatile,transient等) 5)、所有父接口全名的列表类型全名保存的数据结构由虚拟机实现者定义。除此之外,Java虚拟机还要为每个类型保存如下信息: 1)、类型的常量池 2)、类型字段的信息 3)、类型方法的信息 4)、所有的静态类变量(非常量)信息 5)、一个指向类加载器的引用 6)、一个指向Class类的引用
----------------------------------------------------------------------------------------------------------------
个人觉得学习java,对于内存的分析会让自己更明白java的内涵
所以接着也会慢慢的学习java jvm的知识扩展自己的视野