龙二少爷 2008-12-08 10:25
浏览 283
已采纳

问个折磨人的java问题

java中的方法会不会被GC? 它的生命周期有多长? 方法中的变量是如何被分配的?生命周期又是如何?
问题补充
我是知道啊~~就是想看看有多少人有深入去看jvm
问题补充

风花雪月饼 写道
方法被gc?

静态方法?

静态方法不会。启动就存在了。

方法?也不会把,以实例来作为GC的吧。

比如

user.validate()

总不能validate被GC了嘛。

validate中定义的变量会被gc




那指令呢?

  • 写回答

5条回答 默认 最新

  • rednaxelafx 2008-12-09 22:44
    关注

    首先要区分清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有可能会将局部变量优化为直接分配在寄存器上,不过这是实现细节,对上层的程序员并没有可见的影响。

    基本上就是这样吧……

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题