java中的方法会不会被GC? 它的生命周期有多长? 方法中的变量是如何被分配的?生命周期又是如何?
问题补充
我是知道啊~~就是想看看有多少人有深入去看jvm
问题补充
首先要区分清code和data。以后JVM很可能会有新的机制来允许方法(code)被GC,例如说通过新的[url=http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm]AnonymousLoader[/url]、MethodHandle等机制。但就现在的JVM来说,code一旦被ClassLoader给load进来之后就放在PermGen heap上,基本上直到程序终止前都不会被GC了。据说Java 6 Update 4还是多少开始有个新的启动参数,-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses,不过没仔细看不知道到底能达到怎样的效果。
Java中的code是以类为单位保存在class文件里的。Class文件里含有类的名称、继承关系、常量池,以及各个静态/成员方法的字节码。JVM在加载程序的时候也是以类为单位来加载的,code会被加载到称为"Permanent Generation"(PermGen)的堆上。
类的静态变量是在其被加载时先分配空间(可以认为也是在PermGen里),然后初始化。其生命周期与类的code的生命周期一样长。
成员变量则是在new新的实例时分配空间,并由默认初始化器和构造器等初始化。其生命周期与实例的周期相关。注意这里说的生命周期是单纯指primitive type或者reference自身,而不包括reference指向的对象。举例来说,假如一个实例a的成员x被赋为null了,那么这个null值仍然要保存在a里,在32位系统上这就意味着至少占用了4个字节。
方法中的局部变量概念上说是在栈上分配空间的,其生命周期与方法调用的周期一样,也就是说方法调用过后空间就会被回收。注意这里指的同样是primitive type或者reference自身,而不包括reference所指向的对象。再举个例子的话,假如在方法里有这么一句:
[code="java"]String s = new String("abc");[/code]
则"abc"是在常量池里分配空间的,s现在所指向的刚new出来的对象(作为一个实例)是在第0代堆里分配空间,而s(作为一个引用)自身概念上是在栈上分配空间的。方法结束时,s自身的空间会被回收,但s所指向的对象是否被回收取决于是否还存在指向它的活引用。
之所以说是“概念上在栈上分配空间”是因为JVM有可能会将局部变量优化为直接分配在寄存器上,不过这是实现细节,对上层的程序员并没有可见的影响。
基本上就是这样吧……
找本jvm得书看看不久知道了
方法被gc?
静态方法?
静态方法不会。启动就存在了。
方法?也不会把,以实例来作为GC的吧。
比如
user.validate()
总不能validate被GC了嘛。
validate中定义的变量会被gc
没细看过 JVM。通过常识来判断。
任何方法都是跟着class走的。
如果class被GC,方法才会被GC。
方法的生命周期同class一样。
方法中的局部变量分配在运行栈上,生命周期就在 { } 范围内。超出范围,应该很快就会被GC。
GC是针对 在堆中开辟的内存 进行回收变为再次可用。
在java中,取消了手动释放堆内存,为了更安全着想,由JVM自行管理。
也就是所谓的 垃圾回收器。
如果当一个实例 失去引用的时候
例如: Object a = new Object();
a= null;
哪么,这个实例将列入垃圾回收列表。
垃圾回收器,在认为合适的时候,才统一的释放其 所有(在程序中失去引用的对象)的内存。
jdk版本的不同。GC工作方式也不同,但目的都是相同的都是释放堆内存。
方法中的变量 是在栈中开辟的。 当程序离开 方法{} 作用域后。局部变量立即销毁。
由于栈 是通过指针移动来访问数据的,其速度仅次于 CPU直接访问一缓效率。