以下是JVM的一个基本架构图,在这个基本架构图中,栈有两部份,Java线程栈以及本地方法栈,栈的概念与C/C++程序基本上都是一个概念,里面存放的都是栈帧,一个栈帧代表的就是一个函数的调用,在栈帧里面存放了函数的形参,函数的局部变量, 返回地址等,但是与C/C++的一个重要区别是,C/C++里面有传值以及传址的区别,当传的是一个对象时( 结构体也可以当成对象,其实就是对象~,只不过里面的方法默认都是public的,不信你可以试试,在结构体中加一个函数,编译器也不会报错,程序依旧运行~~~),会将对象复到到栈中,而Java中只有基本类型才是传值的,其他类型传的都是引用,什么是引用,学过C/C++的就把引用当作指针理解吧~~~,在这个基本架构图中,可以看出JVM还定义了一个本地方法栈,本地方法栈是为Java调用本地方法【这些本地方法是由其他语言编写的】服务的
上面的图中看到的是JVM中栈有两个,但是堆只有一个,每一个线程都有自已的线程栈【线程栈的大小可以通过设置JVM的-xss参数进行配置,32位系统下,一般默认的大小是512K】,线程栈里面的数据属于该线程私有,但是所有的线程都共享一个堆空间,堆中存放的是对象数据,什么是对象数据,排除法,排除基本类型以及引用类型以外的数据都将放在堆空间中,下面来具体分析一下堆空间...
在JVM中堆空间划分如下图所示
上图中,刻画了Java程序运行时的堆空间,可以简述成如下2条
1.JVM中堆空间可以分成三个大区,新生代、老年代、永久代
2.新生代可以划分为三个区,Eden区,两个幸存区
在JVM运行时,可以通过配置以下参数改变整个JVM堆的配置比例
1.JVM运行时堆的大小 -Xms堆的最小值 -Xmx堆空间的最大值 2.新生代堆空间大小调整 -XX:NewSize新生代的最小值 -XX:MaxNewSize新生代的最大值 -XX:NewRatio设置新生代与老年代在堆空间的大小 -XX:SurvivorRatio新生代中Eden所占区域的大小 3.永久代大小调整 -XX:MaxPermSize 4.其他 -XX:MaxTenuringThreshold,设置将新生代对象转到老年代时需要经过多少次垃圾回收,但是仍然没有被回收
在上面的配置中,老年代所占空间的大小是由-XX:SurvivorRatio这个参数进行配置的,看完了上面的JVM堆空间分配图,可能会奇怪,为啥新生代空间要划分为三个区Eden及两个Survivor区?有何用意?为什么要这么分?要理解这个问题,就得理解一下JVM的垃圾收集机制(复制算法也叫copy算法),步骤如下: