JVM内存模型

JVM基本结构图:

类加载子系统:负责才能够文件系统或者网络中加载class信息,加载的信息存放在方法区。

方法区:存放类信息,常量,常量池,静态常量等

:最主要的java工作内存区域,几乎所有的对象实例都存放在java堆中。常见的堆的结构如下

分为新生代区(eden,s0,s1 (s0,s1也叫做fromto)

老年代区      tenured

:存放局部变量以及自定义对象的引用

程序计数器(和系统相关)

本地方法栈:和java栈很相似,最大不同本地方法栈用于本地方法调用。

垃圾收集器java有一套属于自己的垃圾回收机制,用于内存的回收,无需开发人员手动清理。后面会讲到

执行引擎:执行虚拟机的字节码,一般先编译成机器码后执行。

堆内存详解:

根据回收机制的不同,堆的结构可能不同,最为常见的是把堆分为新生代和老年代,

其中新生代存放刚创建的对象或者年龄不大的对象,老年代则存放老年代对象。

新生代分为eden,s0,s1区(s0,s1区也叫做from区和to区,他们是两块大小相等并且角色可以互换的空间)

绝大数情况下,对象会分配在Eden区,在一次新生代回收以后,如果对象还存活,就进入s0或者s1区,之后每经过一次新生代回收以后,对象的年龄就会加1,达到一定的年龄以后,就会进入老年代。

我们创建一个对象都做了什么?

比如 User u1 = new User();

我们创建类的信息,User类的一些信息是存在方法区的(类信息以及静态信息)

u1 被实例化出来以后是存放在堆中的,当我们去使用都是使用u1的引用,这个u1是存在栈中的

内存分配流程

1. JVM会试图为相关Java对象在Eden中初始化一块内存区域

2. Eden空间足够时,内存申请结束。否则到下一步

3. JVM试图释放在Eden中所有不活跃的对象, 释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor

4. Survivor区被用来作为EdenOLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor

5. OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集

完全垃圾收集后,若SurvivorOLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误

原文地址:https://www.cnblogs.com/javabigdata/p/7374654.html