JVM 堆栈

JVM就是java虚拟机,我们可以将他理解为一个操作系统,在windows和linux中,都会有不同的JVM因为这样,突出了java的一个重要特点,跨平台性。

 

一、栈

       jvm中,栈用于储存局部变量,对象的引用和方法中计算过程的数据,在退出方法后,就会清除,存储速度对比堆快得多,只比计算机的寄存器要慢。

例如,循环中定义的变量就是局部变量,在循环过一次之后就会释放,然后进入下一次循环重新定义,所以局部变量的生命周期都很短。

二、堆

        jvm中储存程序中的对象,比如使用了new关键字的对象,都是会存储在堆中,堆主要分为三个区域新生代,老年代和持久代。

1。新生代

       用于存放新生的对象,在程序运行的过程中新生的对象都会存放在新生代中,新生代中也分为三个区域,eden , s0 和 s1 区域。

所有新生的对象一开始都会进入到eden区中,在经过GC的一次回收之后,如果对象还没有被销毁,他就会从eden区移动到s0或者s1区域中。

具体分配到哪个区域我们先看一下s0和s1区。

1.1 s0和s1      

    s0和s1是两个完全一样的区域,同样的大小,并且可以随时变换角色的一个内存区域,这两个区域中,GC有一个专们的垃圾回收算法:

复制算法,所有经过eden区域并且在GC扫描过后没有被销毁的对象,都会在程序第一次进行垃圾回收之后进入到s0中,然后程序照常运行。

在GC第二次扫描的时候,如果在s0中内存中的对象程序还在使用的话,就会将他的内存地址复制到s1中,在扫描完s0中的所有对象后,GC就会

将s0中的所有对象清空,然后之后的引用都会使用s1区域中的对象。

2。老年代

      在新生代中,每次GC在进行垃圾回收的时候,都会给对象的年龄+1,如果这个对象的年龄,经过了一定的阈值,就会进入到老年代中,但是一些比较大的对象,

这些大对象可以不经过新生代,直接进入老年代,这样可以防止新生代中有大量剩余空间时,大对象的创建导致提前发生GC和S0和S1中大对象的复制的性能问题。

而且大的数组对象也会直接存放到老年代中,比如list和Arraylist对象,因为集合对象会在内存中创建一个连续的内存空间存储数据。

例如  int [] arr=new int [3]; 新建一个数组对象,它会现在栈中定义一个变量arr,因为右边不是一个具体的值,而是一个对象所以会在堆中开辟一个连续的内存空,

将引用地址存储到栈的变量中,而操作变量的时候就根据地址去堆中找这个实例,而不是在栈中来开辟这个空间。这种不叫基本数据类型,而是引用数据类型。

3。持久代

     持久代则是用来储存class、method元信息,大小配置和项目规模等信息等。

 

 

posted @ 2018-10-10 15:19  WildY  阅读(405)  评论(0)    收藏  举报