Java 栈是由许多帧(frame)组成的,一个帧包含一个Java方法调用的状态。当线程调用一个Java方法时,虚拟机压入一个新的帧至该线程序的Java栈中,当该方法返回时,这个帧被从该线程所属的栈中弹出。
Java中每个线程都有自己独立的栈。
public class Hello{
private Hello(){
new Hello();
}
public static void main(String args[]){
new Hello();
}
}
如上代码将产生异常:
Exception in thread "main" java.lang.StackOverflowError
at com.livedoor.classcode.Hello.<init>(Hello.java:9)
at com.livedoor.classcode.Hello.<init>(Hello.java:9)
at com.livedoor.classcode.Hello.<init>(Hello.java:9)
at com.livedoor.classcode.Hello.<init>(Hello.java:9)
异常明确提示 栈 溢出了。
Java 堆(heap) 是用于保存 java对象的。实际上就是Java 的 object pool.
所有的java对象都放在了这个pool中。
如下代码:
public class Hello{
private Hello(){
List aa=new ArrayList();
for(int i=0;i<10000000;i++){
aa.add(new String("dd"));
}
System.out.println("OK");
}
public static void main(String args[]){
new Hello();
}
}
异常:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
则表是产生的对象过多,超出了heap的限制。
Java程序在运行时创建的所有类实例或数组都放在同一个堆中。而一个Java虚拟机实例中只存在一个堆空间,因此所有线程都将共享这个堆。Java虚拟机有一条在堆中分配新对象的指令(没有释放内存的指令)。正如你无法用Java代码去明确释放一个对象一样,字节码指令也没有对应的功能。虚拟机自己负责决定如何以及何时释放不再被运行的程序引用的对象所占据的堆内存。
-------------------------------------------------
以上两种异常经常被混消。如果出现stack溢出异常很可能是因为某个方法产生了死递归调用。
而heap溢出的话可能要麻烦一些,查找起来原因也费事一些。
Java中每个线程都有自己独立的栈。
public class Hello{
private Hello(){
new Hello();
}
public static void main(String args[]){
new Hello();
}
}
如上代码将产生异常:
Exception in thread "main" java.lang.StackOverflowError
at com.livedoor.classcode.Hello.<init>(Hello.java:9)
at com.livedoor.classcode.Hello.<init>(Hello.java:9)
at com.livedoor.classcode.Hello.<init>(Hello.java:9)
at com.livedoor.classcode.Hello.<init>(Hello.java:9)
异常明确提示 栈 溢出了。
Java 堆(heap) 是用于保存 java对象的。实际上就是Java 的 object pool.
所有的java对象都放在了这个pool中。
如下代码:
public class Hello{
private Hello(){
List aa=new ArrayList();
for(int i=0;i<10000000;i++){
aa.add(new String("dd"));
}
System.out.println("OK");
}
public static void main(String args[]){
new Hello();
}
}
异常:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
则表是产生的对象过多,超出了heap的限制。
Java程序在运行时创建的所有类实例或数组都放在同一个堆中。而一个Java虚拟机实例中只存在一个堆空间,因此所有线程都将共享这个堆。Java虚拟机有一条在堆中分配新对象的指令(没有释放内存的指令)。正如你无法用Java代码去明确释放一个对象一样,字节码指令也没有对应的功能。虚拟机自己负责决定如何以及何时释放不再被运行的程序引用的对象所占据的堆内存。
-------------------------------------------------
以上两种异常经常被混消。如果出现stack溢出异常很可能是因为某个方法产生了死递归调用。
而heap溢出的话可能要麻烦一些,查找起来原因也费事一些。