我想问一下对象是加载在堆中,那类是加载在哪里的?还有类里面的静态方法和非静态方法也是加载在同一个区域吗?
类加载在方法区。都在同一区域。
我好像就知道堆,栈,方法区。那静态类也是加载在方法区的哇。方法区里面是不是泾渭分明,静态类放在一块地方,非静态类放在一块地方
@给点阳光yh: 方法区就是加载类文件的时候使用的一块内存,静态方法和非静态方法都随类同时加载,区别在于静态方法已经绑定,而非静态方法是在构造实例对象时绑定(如果实例没有创建如何绑定?).
这个没想这么细,我只知道类加载在内存里,非静态方法会隐性地传一个this指针进去,对应对象的数据。
类的主要作用是用来创建对象,在程序中单纯的创建类而不创建对象是没有什么实际意义的,也就是说如果你只是单纯的创建类而不创建该类对象,就表明它没有被使用,也就是冗余代码,程序在运行时会一扫而过,对于C#而言也就会被GC掉,不存在楼主说的这个牛角尖!
那静态类是一开始就被加载的把,好像JAVA都没有静态类的
@给点阳光yh: Java里面不清楚,但是对于C#中静态类也是会放在堆中的!
@hippieZhou: 哎,我也是醉了,怎么说的都有,有没有什么书籍是写这个的呀
@给点阳光yh: 你可以看看图灵图书的深入理解C#这本书!
@hippieZhou: 谢谢哦,现在是想理解深入一点,但是太复杂也看不懂没学过汇编之类的底层语言,尴尬
我想问一下对象是加载在堆中,那类是加载在哪里的?
答:堆中
还有类里面的静态方法和非静态方法也是加载在同一个区域吗?
答:是同一个区,而且他们在底层存储,还有生成时没有任何区别。CLR只是在调用静态函数与非静态函数时,使用不同的方式。
<CLR Via C#>第4章的例子,我用最简单的方式描述一下,如下图:
程序在某一时刻打算执行图左下角函数M3的几行代码,CLR的执行过程是这样的:
1、CLR查看M3函数中的所有类型(Int32/Employee/Manager等)是否都加载?
2、如果没有加载,则创建一个数据结构来表示这个类型,就是我们常说的类,比如图中最右边的Manager/Employee,这个结构会有函数表来存放函数信息,其实这个结构只是Type类型的实例;
3、执行到:e = new Manager();时,CLR会在堆上又创建一个结构,即Manager对象,它里面有一个指针(类型对象指针),指向它所属的类的结构;
4、CLR执行Employee.Lookup时,发现是所谓的静态函数,JIT编译器直接“定位与定义该方法的类型对应的Type实例,然后在该实例的函数表中查找方法,并执行”,从而静态函数得到执行;
5、 CLR执行e.GetYearsEmployed()时,发现是一般的函数(非虚),JIT编译器执行 A:查找变量e定义时的类型(即Employee,而不是Manager),B:在该类型的Type实例函数表中查找方法,并执行;就比静态函数多一个过程,但它有一个前提:要生成对象,所以效率比静态要低;
6、CLR执行到e.GenProgressReport()时,发现是一个虚函数,过程就更复杂了:A: JIT额外生成一些代码,该代码查找e定义时的变量,根据变量的引用地址,找到堆中的实际对象,即Manager对象,B:代码查找对象内部的“类型对象指针”,看该指针指向的Type实例,C:在该Type实例函数表中查找方法,并执行;
其实就这么点不同!!详细内容建议认真阅读<CLR Via C#>
放在堆中 静态的是存于方法区中的
所有的数据都是在内存中,脱离堆,栈等名词其实就更好理解点,不要过意纠结堆和栈这些东西