这篇帖子是我们 2005-8-18 日写的
在 Java 里,静态字段是常驻内存中的,但是静态方法是否也是常驻内存中呢?
来自 comp.lang.java.programmer 的回答:
------------------------------------
John Bollinger answered:
All instance fields of every object in the JVM and all static fields of every class in the JVM are always in (possibly virtual) memory. Some version of the code for all methods, static and non-static, of all classes currently loaded in the JVM are always in (possibly virtual) memory. These are direct implications of an instance being live in a JVM and of a class being loaded in a JVM. Why do you suggest otherwise?
Methods do not run in any case. Threads run, executing methods' code in the process.
----------------------------------------
Roedy Green answered:
They hang around in RAM until there are no more references to them. Then they can be GCed like anything else.
--------------------------------------------------
那么,是不是这样呢?
在 JVM 中,所有对象的的静态字段与实例字段都是在内存中,(对于实例字段来说,只有对象实例化才在内存中)
对于方法来说,只要类已经被 load 进 JVM,则不论其是否静态,都存在于内存中,区别只是对于静态方法,所有的实例及对象都指向同一个方法。
--------------------------------------------------
following is writed by me
then,does it work like following? 1. when class isn't be loaded in JVM --all fields not in memory
2. when class is loaded in JVM --static fields are in memory,but instance fields aren't in memory,all methods not in memory
3. when class is loaded in JVM,but it isn't be initialized,and its static method is invoked --all fields are in memory,static methods in memory,but instance methods aren't in memory 4. when class is initialized --all fields are in memory,all methods are in memory 5. Whether it's true or not? and at last,I want to know when are they be GCed? I'm puzzled by Roedy,static fields can be GCed? And static methods too?
-------------------------------------------------
Chris Uppal answered:
> then,does it work like following?
> 1.[...]
No. The following is a simplification (there are exceptions in certain "advanced" situation -- all of which involve classloaders), but it's close enough for a working approximation:
When a class is loaded, the code for its instance methods and static methods are treated identically. They are copied into the JVM's memory and stay there (with the class itself) until the JVM exits. Nothing is ever GCed.
Instance fields are part of the instances, so the memory used for storing any instance's fields is allocated when the instance is created, and released when the instance is GCed. Static fields are part of the class, and their memory is allocated when the class is loaded, and never released until the JVM exits. (Or until the class is itself GCed -- but that can never happen except in special applications which make sophisticated use of classloaders)
(Actually, the JVM is at liberty to play tricks to reduce memory consumption, as long as that is never visible to application programmers. That's an implementation detail, and will vary from JVM to JVM. As far as I, personally, know the only "trick" that is used is that the JITed form of the methods' code /can/ be created lazily (when the method is used, or is used more than a certain number of times), and that the compiled machine-code representation /can/ be thrown away if it has not been used for a while.)
> I'm puzzled by Roedy,static fields can be GCed? And static methods > too?
Roedy is wrong. If he is confusing you then it's probably best just to ignore him (on this subject).
=========================
现在我基本明白了,结论如下,欢迎拍砖:
1、class 没有 load 进 JVM 前,所有的 fields ,methods 均不在内存中
2、class 被 load 进 JVM 后
a. 对于方法
不论是 static 或 非 static 的,都一样的,总是跟 class 本身在一起的(即存放在内存中),永远不会被回收,除非 JVM 退出。他们的区别是,静态的方法不需要实例即可使用,而非静态的方法需要实例调用。
那么,除了安全的考虑外,以于使用者来说,调用 static 方法更方便,但并不会对内存造成额外的开销。
b. 对于属性
静态属性是跟 class 相关的,所以总是当 class 被 load 进 JVM 时即存在于内存中,并不会被垃圾回收(所以,相比于实例属性,对于内存来说是有多余的开销的)。
静态属性被回收的唯一情况是类本身被回收,这种情况的发生只有当某个应用单独使用了一种复杂的类装载器的时候才可能出现。
实例属性是跟实例相关的,故只有类实例化后,才会放入内存,当实例被回收后,实例属性自然也不存在了。
Roedy 依然认为 static field 与 static Method 是可以回收的(从广义上来说应该是这样,有时间我研究一下 JVM 的规范再说):
-----------------------------------------------------
Roedy answered:
>Static *methods* ?? Surely not. And what's a reference to a static method?
A piece of code that invokes a static method would be a reference to a static method, but GC is only interested in what class references point to, not which method within that class.
On the other hand, a method might be inlined, interpreted or compiled. Over a session it might even exist in all three forms. Each method of the class can be handled separately. Presumably GC scavenges discarded compilations whose "effectively final" assumptions have been ruined by a new class loaded.
2007年11月19日星期一
订阅:
博文评论 (Atom)
没有评论:
发表评论