JVM调优学习(一):基本概念

转载:http://pengjiaheng.iteye.com/blog/518623

数据类型

Java虚拟机中,数据类型可以分为两类:基本类型引用类型

基本类型的变量保存原始值,即:他代表的值就是数值本身。

引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。

基本类型包括:byte,short,int,long,char,float,double,Boolean,returnAddress

引用类型包括:类类型接口类型数组

堆与栈

JVM调优学习(一):基本概念

栈是运行时的单位,而堆是存储的单位

栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;

堆解决的是数据存储的问题,即数据怎么放、放在哪儿

为什么要把堆和栈区分出来?栈中不是也可以存储数据吗?

一、从软件设计的角度来看,栈代表处理逻辑,堆代表数据。分开使得处理逻辑更加清晰,体现了隔离、模块化的设计思想

二、堆栈分离,使得堆中内容可被多个栈共享,即多个线程访问同一个对象。一方面这种共享提供了一种有效的数据交互方式(如:共享内存),另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间

三、由于栈只能向上增长,会限制住栈存储内容的能力,而堆中的对象可以根据需要动态增长,所以,堆栈分离,使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可

四、面向对象就是堆和栈的完美结合。对象的属性其实就是数据,存放在堆中;而对象的行为(方法),就是运行逻辑,放在栈中。我们编写对象的时候,既编写了数据结构,也编写了处理数据的逻辑。

在Java中,main函数就是栈的起始点,也是程序的起始点

堆中存什么?栈中存什么?

堆中存的是对象,栈中存的是基本数据类型和堆中对象的引用。

为什么基本类型不放堆中,因为基本类型字节少,占用空间少,而且长度固定,不会动态增长,所以放栈中节省空间。

Java中的参数传递是传值还是传引用?

程序运行永远是在栈中进行,而栈保存的是基本数据类型和堆中对象的引用,传参变量保存的是基本数据类型值本身或者对象的引用值,所以,是传值。

Java中,栈的大小通过-Xss来设置,当栈中存储数据较多时需要提高这个值,否则会出现java.lang.StackOverflowError异常。

堆栈分离,使得java垃圾回收机制成为可能。

Java对象的大小

一个空Object对象的大小是8byte,但是Object ob = new Object()这样一个无属性对象所占空间为4byte+8byte。因为4byte是栈中保存引用所需要的空间,而8byte则是堆中对象的信息。

Class NewObject {

    int count;

    boolean flag;

    Object ob;

}

其大小为:空对象大小(8byte)+int大小(4byte)+boolean大小(1byte)+空Object引用的大小(4byte)=17byte,但因为java对象在分配内存时都是以8的整数倍来分,因此大于17的最接近8的倍数是24,因此此对象大小为24byte。

引用类型

对象引用分为强引用、软引用、弱引用和虚引用。

强引用:一般声明对象时虚拟机生成的引用。强引用环境下,垃圾回收时需要严格判断当前对象是否被强引用,若是,则不会被垃圾回收。

软引用:一般被作为缓存来使用。如果剩余内存紧张,则虚拟机会回收软引用引用的空间;如果相对富裕,则不会回收。虚拟机发生OutOfMemory时,肯定是没有软引用存在的。

弱引用:与软引用类似,也是作为缓存使用。弱引用生命周期只存在一个垃圾回收周期内,进行垃圾回收时一定会被回收。