java虚拟机可能是下面三个中的一个
1:抽象规范
2:一个具体实现
3:一个虚拟机实例
java虚拟机的生命周期
java虚拟机的天职就是:运行一个java程序.当一个java程序运行开始运行时,一个虚拟机实例就产生了.当一个计算机上同时运行三个java程序.则将产生三个java虚拟机实例.每个程序运行在自己的虚拟机里面,不会干扰.当程序运行完毕时,虚拟机将自动退出.
java虚拟机里面有两种线程,守护线程和非守护线程.守护线程是说java虚拟机自己的线程,如垃圾收集线程.而非守护线程则是java中运行的程序线程.当非守护线程都运行完了.java虚拟机将退出.
一个java虚拟机主要包括了:类转载子系统,运行时数据区,执行引擎,内存区等等.
运行时数据区------主要是:1 堆 2 方法区 3 java栈
堆和方法区对虚拟机实例中所有的对象都是共享的.而java栈区,是对每个线程都是独立的. 当一个class被载入到 classloader中时,会解析它的类型信息.把这些类型信息放到方法区,而把程序中运行的对象,放到堆区.当一个新线程被创建,就分配一个新的java栈.java栈中保存的,是方法中的一些变量,状态.java栈是由很多的java栈帧组成的.一个栈帧包含了一个方法运行的状态.当一个方法被执行的时候,就压入一个新的java栈帧到java栈中,方法返回的时候,就把栈帧弹出来,抛弃掉.
方法区
在java虚拟机中,被装载的类的类型信息和类的静态变量被存储在方法区这样的内存里面.java程序运行时,会查找这些个信息.方法区的大小,是动态的.也可以不是连续的.可自由在堆中分配.也可以由用户或者程序员指定.方法区可被垃圾收集.
方法区可以保存以下信息
这个类型的全限定名
直接超类的全限定名
是类类型还是接口
类型的访问修饰符
任何直接超类接口的全限定名的有序列表.
该类型的常量池
字段信息 类中声明的每个字段及其顺序 如字段名,类型.修饰符号.
方法信息:如方法名,返回类型.参数表列.修饰符号.字节码.操作数栈和栈帧中局部变量区大小等等
类静态变量
一个到类classloader的引用
一个到class类的引用
堆
用来存储运行时的对象实例
java栈
每启动一个新的线程.就会分配到一个java栈.java栈以帧为单位保存线程的运行状态.它有两种操作.入栈,出栈.
当一个方法被调用时,入栈,当一个方法返回时,出栈,或者当方法出现异常.也出栈.
栈帧
组成部分 局部变量区,操作数栈,帧数据区.
posted @
2006-04-05 18:25 dodoma 阅读(370) |
评论 (1) |
编辑 收藏
Eliminate obsolete object references消除过期的对象引用
When you switch from a language with manual memory management, such as C or C++, to agarbage-collected language, your job as a programmer is made much easier by the fact that your objects are automatically reclaimed when you're through with them. It seems almost like magic when you first experience it. It can easily lead to the impression that you don't have to think about memory management, but this isn't quite true.
java中也要注意内存管理
// Can you spot the "memory leak"?
public class Stack {
private Object[] elements;
private int size = 0;
public Stack(int initialCapacity) {
this.elements = new Object[initialCapacity];
}
Effective Java: Programming Language Guide
17
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
/**
* Ensure space for at least one more element, roughly
* doubling the capacity each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size) {
Object[] oldElements = elements;
elements = new Object[2 * elements.length + 1];
System.arraycopy(oldElements, 0, elements, 0, size);
}
}
}
这里有一个内存泄漏
如果一个栈先是增长,然后再收缩,那么,从栈中弹出来的对象将不会被当做垃圾回收,即使使用栈的客户程序不再引用这些对象,它们也不会被回收。这是因为,栈内部维护着对这些对象的过期引用(obsolete re f e re n c e)。所谓过期引用,是指永远也不会再被解除的引用
改正
public Object pop() {
if (size==0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference清除引用
return result;
}
当程序员第一次被类似这样的问题困扰的时候,他们往往会过分小心:对于每一个对象引用,一旦程序不再用到它,就把它清空。这样做既没必要,也不是我们所期望的,因为这样做会把程序代码弄得很乱,并且可以想像还会降低程序的性能。“清空对象引用”这样的操作应该是一种例外,而不是一种规范行为。消除过期引用最好的方法是重用一个本来已经包含对象引用的变量,或者让这个变量结束其生命周期。如果你是在最紧凑的作用域范围内定义每一个变量(见第2 9条),则这种情形就会自然而然地发生。应该注意到,在目前的J V M实现平台上,仅仅退出定义变量的代码块是不够的,要想使引用消失,必须退出包含该变量的方法。
一般而言,只要一个类自己管理它的内存,程序员就应该警惕内存泄漏问题。一旦一个元素被释放掉,则该元素中包含的任何对象引用应该要被清空。
内存泄漏的另一个常见来源是缓存。一旦你把一个对象引用放到一个缓存中,它就很容易被遗忘掉,从而使得它不再有用之后很长一段时间内仍然留在缓存中
posted @
2006-03-31 16:35 dodoma 阅读(200) |
评论 (0) |
编辑 收藏
Avoid creating duplicate objects避免创建重复的对象
It is often appropriate to reuse a single object instead of creating a new functionally equivalent object each time it is needed. Reuse can be both faster and more stylish. An object can always be reused if it is immutable
String s = new String("silly"); // DON'T DO THIS!
String s = "No longer silly";//do this
In addition to reusing immutable objects, you can also reuse mutable objects that you know will not be modified. Here is a slightly more subtle and much more common example of what not to do, involving mutable objects that are never modified once their values have been computed:
除了重用非可变的对象之外,对于那些已知不会被修改的可变对象,你也可以重用它们。
such as
public class Person {
private final Date birthDate;
// Other fields omitted
public Person(Date birthDate) {
this.birthDate = birthDate;
}
// DON'T DO THIS!
public boolean isBabyBoomer() {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd = gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0 &&
birthDate.compareTo(boomEnd) < 0;
}
}
改良的版本.
The isBabyBoomer method unnecessarily creates a new Calendar, TimeZone, and two Date instances each time it is invoked. The version that follows avoids this inefficiency with a static initializer:
class Person {
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
/**
* The starting and ending dates of the baby boom.
*/
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0 &&
birthDate.compareTo(BOOM_END) < 0;
}
}
。一个适配器是指这样一个对象:它把功能委
托给后面的一个对象,从而为后面的对象提供一个可选的接口。由于适配器除了后面的对象之外,没有其他的状态信息,所以针对某个给定对象的特定适配器而言,它不需要创建多个适配器实例。
This item should not be misconstrued to imply that object creation is expensive and should be avoided. On the contrary, the creation and reclamation of small objects whose constructors do little explicit work is cheap, especially on modern JVM implementations. Creating additional objects to enhance the clarity, simplicity, or power of a program is generally a good thing.
Conversely, avoiding object creation by maintaining your own object pool is a bad idea unless the objects in the pool are extremely heavyweight. A prototypical example of an object that does justify an object pool is a database connection. The cost of establishing the connection is sufficiently high that it makes sense to reuse these objects. Generally speaking, however, maintaining your own object pools clutters up your code, increases memory footprint, and harms performance. Modern JVM implementations have highly optimized garbage collectors that easily outperform such object pools on lightweight objects.
posted @
2006-03-31 15:19 dodoma 阅读(199) |
评论 (0) |
编辑 收藏