jvm基本结构
常用jvm虚拟机参数
-Xmx: 系统最大可用堆空间
- 栈和函数调用关系
局部变量表
当调用的函数的局部变量个数不同时,会影响递归的深度
局部变量在函数调用结束后,会随着函数销毁
public class TestStackDeep {
private static int count=0;
public static void recursion(long a,long b,long c){
long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=10;
count++;
recursion(a,b,c);
}
public static void recursion(){
count++;
recursion();
}
public static void main(String args[]){
try{
recursion(0L,0L,0L);
//recursion();
}catch(Throwable e){
System.out.println("deep of calling = "+count);
//e.printStackTrace();
}
}
}
localvar2的b变量可以复用a的位置
localvar1就不行
public class LocalVar {
public void localvar1(){
int a=0;
System.out.println(a);
int b=0;
}
public void localvar2(){
{
int a=0;
System.out.println(a);
}
int b=0;
}
public static void main(String[] args) {
}
}
public class LocalVarGC {
public void localvarGc1() {
byte[] a = new byte[6 * 1024 * 1024];
System.gc();
}
申请空间后立即回收,因为a还在被引用,所以无法回收
public void localvarGc2() {
byte[] a = new byte[6 * 1024 * 1024];
a = null;
System.gc();
}
垃圾回收前将变量a设置为null,byte数组失去引用,所以可以回收
public void localvarGc3() {
{
byte[] a = new byte[6 * 1024 * 1024];
}
System.gc();
}
垃圾回收前,局部变量a失效,虽然a已经离开了作用域,但a还在局部变量中,所以不能回收
public void localvarGc4() {
{
byte[] a = new byte[6 * 1024 * 1024];
}
int c = 10;
System.gc();
}
回收之前,a失效,并且c重用了a局部变量的位置,所以a已经被销毁,可以回收
public void localvarGc5() {
localvarGc1();
System.gc();
}
可以回收
public static void main(String[] args) {
LocalVarGC ins = new LocalVarGC();
// ins.localvarGc1();
// ins.localvarGc2();
// ins.localvarGc3();
ins.localvarGc4();
}
操作数栈
保存计算中间结构
帧数据区
保存这访问常量池的指针,方便程序访问常量池
保存着异常处理表
栈上分配:对于那些线程私有对象,可以分配栈上,而不是堆上,可以避免垃圾回收
如果生成大量反射对象,则有可能元数据空间不够用
public static void main(String[] args) {
int i = 0;
try {
for (i = 0; i < 10000; i++) {
CglibBean bean = new CglibBean("geym.zbase.ch2.perm" + i, new HashMap());
}
} catch (Exception e) {
System.out.println("total create count:" + i);
throw e;
}
}
jdk1.7设置方法区(永久区)大小: -XX:PermSize=10m -XX:MaxPermSize=10m
jdk1.8设置元数据区: -XX:MaxMetaspaceSize=10m