我们知道在java中创建对象最简单的方式就是 new 但是 在这简单的new之后,jvm到底是怎么给我们这个实例对象分配内存的,
1首先我们要理解jvm中的内存模型jvm中内存模型从大了说,主要分为栈内存,堆内存,当然还有一些其他的包括寄存器,线程栈等等,今天我重点说一下堆内存结构模型
堆内存里面在细分新生代,旧生代,新生代包括一个eden区和两个survivo区
当申请新对象的时候内存申请过程如下:
a、jvm先尝试在eden区分配新建对象所需的内存;
b、如果内存大小足够,申请结束,否则下一步;
c、jvm启动youngGC,试图将eden区中不活跃的对象释放掉,释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;
d、Survivor区被用来作为Eden及old的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区;
e、 当OLD区空间不够时,JVM会在OLD区进行full GC;
f、full GC后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”:
outOfMemoryError:javaheap space
2 方法区内存溢出(outOfMemoryError:permgem space)
在jvm规范中,方法区主要存放的是类信息、常量、静态变量等。
所以如果程序加载的类过多,或者使用反射、gclib等这种动态代理生成类的技术,就可能导致该区发生内存溢出,一般该区发生内存溢出时的错误信息为:
outOfMemoryError:permgem space
线程栈溢出(java.lang.StackOverflowError)
线程栈时线程独有的一块内存结构,所以线程栈发生问题必定是某个线程运行时产生的错误。
一般线程栈溢出是由于递归太深或方法调用层级过多导致的。
发生栈溢出的错误信息为:
java.lang.StackOverflowError