对于一个已经编译好的程序,jvm都会把哪些东西放在
内存中呢?以及放在内存中的哪个地方呢?
jvm在运行的时候类加载器首先会把
classpath路径下的所有.class文件读入内存的方法区中。
方法区是
线程共享的,所以要考虑
线程安全的问题。
方法区的大小不是固定不变的,jvm可以进行动态调整。
方法区同样存在垃圾收集,因为通过用户定义的类加载器可以动态扩展java程序,一些类也会成为垃圾。jvm可以回收一个未被引用类所占的空间,以使方法区的空间最小。
对于加载的每一个类都要存储该类的信息如下:
1.这个类型的全名(报名.类名);
2.该类的直接父类的全名;
3.该类的访问修饰符(public,abstract,final);
4.该类实现的
接口的集合;
5.该类的常量池;(jvm为加载的每一个类都维护一个常量池,常量池存储了该类所使用到的所有类型,域和方法的符号引用,)
6.Field信息(变量名,类型,访问修饰符);
7.Method信息(方法名,方法的返回类型,方法参数的数量和类型,方法的修饰符);
8.static变量(类变量被类的所有实例共享,即使没有类实例时你也可以访问它。这些变量只与类相关,所以在方法区中,它们成为类数据在逻辑上的一部分。在jvm使用一个类之前,它必须在方法区中为每个non-final类变量分配空间)(
实例变量是在new的时候分配变量的内存,而static变量是在类加载的时候已经分配空间,并可以通过static静态块进行初始化);
9.对类加载器的引用(jvm需要知道该类是由哪个类加载器加载的);