jvm的内存如何分配使用?

来源:互联网 发布:sql注入站点 编辑:程序博客网 时间:2024/05/01 14:31

jvm内存的划分:    

未初始化

初始化

正文段

粗略的说,jvm内存大致分两块:堆heap和非堆permanent;

从英文翻译上看,非堆permanent是“持久”的意思,它应该是存储需要持久存在的数据,而堆heap相对的就是不持久的数据区;

但我怎么感觉堆heap才是持久的数据区呢?你看非堆permanent中的“栈”跟“客栈”一个字,客栈明显住不长久,还怎么持久;

具体如何:

堆heap: 存储所有的类实例,为数组内存分配空间;堆分为:young generation 和 old generation;

           young generation: 1*(eden sapce) + 2*(Surviver space)(from、to)

                                            Eden:伊甸园     ------- 存放新生的对象(new 对象)

                                            Surviver:存活者  ------- 经历过垃圾回收后存活下来的对象

           old generation: 存放生命周期长的对象;

非堆permanent:  存储java的类信息,包括解析后得到的方法、属性、字段等;不参与垃圾回收;


JVM内存申请过程如下:

  1. JVM 会试图为相关Java对象在Eden中初始化一块内存区域
  2. 当Eden空间足够时,内存申请结束;否则到下一步
  3. JVM 试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区
  4. Survivor区被用来作为Eden的old的中间交换区域,当old区空间足够时,Survivor区的对象会被移到old区,否则会被保留在Survivor区
  5. 当old区空间不够时,JVM 会在old区进行完全的垃圾收集(0级)
  6. 完全垃圾收集后,若Survivor及old区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory”错误



关于栈:

Java栈是与每一个线程关联的,JVM在创建每一个线程的时候,会分配一定的栈空间给线程。它主要用来存储线程执行过程中的局部变量,方法的返回值,以及方法调用上下文。栈空间随着线程的终止而释放。

Java堆是被所有线程共享的;


现在看来,我感觉jvm的分类应该再扩展下,分:堆、非堆、栈,我把java代码需要加载的东西分为:类源码、类对象(new)、类源码方法、类源码变量、对象方法、对象变量、参数;

类源码----------------------->非堆

源码方法----------------------->非堆

源码变量----------------------->非堆

类对象--------------------------->堆

对象方法--------------------------->

对象变量--------------------------->

参数---------------------------------->栈


全局变量(成员变量)是在创建对象的时候分配内存;

点评:其实类源码包括了源码方法、源码变量,类对象包括了对象方法、对象变量;这样再分出来的确多此一举。但这是为了自己更好一一对照、强调,纯属个人习惯... ...

java中的类大致分为三种(这是摘录别人的):

    1.系统类 

    2.扩展类 

    3.由程序员自定义的类



     

0 0
原创粉丝点击