JVM内存划分总结

简介: JDK8 虚拟机内存划分概述在说jvm内存划分之前,先来说下java程序具体的执行流程:  Java源文件经过java编译器编译后变成class字节码文件,Jvm的classloader加载class文件完成后,交由execution engine执行。

JDK8 虚拟机内存划分

概述

在说jvm内存划分之前,先来说下java程序具体的执行流程:

 

 

Java源文件经过java编译器编译后变成class字节码文件,

Jvmclassloader加载class文件完成后,交由execution engine执行。

执行引擎执行过程中用到的所有数据和信息,都存储在runtime data area中。

Runtime data  area 就是我们常说的JVM内存。

 

Runtime data area 

 

Runtime data area 都包括什么呢?

 

Java虚拟机规范》中规定,运行时数据区,主要包含:本地方法栈(native method stack),java栈(VM stack),程序计数器(programs counter register),堆(heap),方法区(method area)。

 

《java虚拟机规范》虽然规定了虚拟机应该包含哪些部分,但是并没有具体的实现规定,所以不同的虚拟机会有不同的实现方式。

 

 

Runtime data area都存放哪些数据?

1,程序计数器(PC寄存器)

 

程序计数器:保存的是正在执行命令的内存地址(java se8虚拟机规范)。

在得到指令地址后,程序计数器会自动指向下一条指令的内存地址。具体实现视不同是虚拟机而定,这里讲的只是概念和程序计数器的作用。

 

JVM中,多线程是轮流获取cpu执行权的,所以,每个线程都会有自己的程序计数器。并且他们不会互相干扰。

 

JVM规范中,如果当前程序执行的是native方法,程序计数器中的值应该是下一条指令的地址,如果是非native方法,程序计数器中的值应该是undefined

 

由于程序计数器中存储的数据占用的空间,不会随程序的执行发生改变,所以程序计数器不会发生内存溢出现象。

 

2java

Java栈也叫虚拟机栈,也就是我们常说的栈,java栈是java方法执行的内存模型。

 

Java栈中存放的是一个个的栈帧,每个栈帧包括:局部变量表,操作数栈,运行时常量池的引用,方法返回地址,附加信息。

 

当线程调用一个方法的时候,就会创建一个栈帧,并且进行压栈操作。方法执行完毕后出栈。由此可知,线程当前执行的方法一定是在栈顶的。到这里大家应该明白了,为什么递归的时候,一个不注意就会栈溢出了。栈这部分空间对程序员而言是不透明的,完全由系统自动实施。

 

 

 

 

栈帧中的各部分都是什么呢?

 

局部变量表

局部变量表:存储方法中的局部变量,局部变量分基本数据类型和引用数据类型,

针对基本数据类型的变量,存储的是值(每种基本数据类型都有固定的内存占用大小),引用数据类型的变量存储的是对象的引用。局部变量表的大小,在编译器时期就可以确定,所以程序执行期间,局部变量表的大小是不会发生改变的。

 

操作数栈:线程执行方法的过程,实际上就是执行语句的过程,归根到底就是计算机计算的过程。然而程序中所有的计算都是借住于操作数栈来完成的。可以理解成,它就是用来做计算的。

 

运行时常量池的引用:方法执行过程中可能会用到类中的常量,必须要有一个引用指向运行时常量。

 

方法返回地址:方法执行完成后,要返回之前调用它的地方,因此栈帧中必须保存方法的返回地址。

 

附加信息:java虚拟机规范允许一些虚拟机的具体实现增加一些规范中没有描述的信息到栈帧中,例如与调试相关的信息,这部分信息完全取决于虚拟机的具体实现。

 

3,本地方法栈

本地方法栈和java栈的原理和作用是非常相似的。区别是值java栈是为执行java方法执行服务的。本地方法栈是执行为native方法服务的。JVM规范中并没有对本地方发展的具体实现和数据接口做强制规定,虚拟机的具体实现可以自由实现它。比如hotSopt虚拟机中的实现就是将本地方法栈和java栈合二为一。

 

4,堆

Java中的堆是用来存储对象本身和数组的(数组的指针在java栈中)。

堆这部分空间是java垃圾回收的主要区域。

堆是被所有线程共享的,在JVM中只有一个堆。

 

JDK8中的堆内分划分和JDK7是不一样的,JDK7以及之前的版本 PermGen Space 是在堆中的,当永久代满了之后会报 OutOfMemoryError:PermGen Space 错误。

JDK8中永久代就不在堆中了,而是移到了本地内存中,会根据永久代对象的大小动态调整metaSpace区的大小。

JDK8也提供了设置metaspace大小的参数,-XX:MaxMetaspaceSize=128M 

如果不设置JVM将会根据一定的策略自动增加本地元内存空间。

如果设置的元内存空间过小,

你的应用程序可能得到以下错误:OutOfMemoryError:metadata space.

 

 

 

4.1

Eden: 

对象创建,最初是在这个内存池中分配内存的。

eden区满的时候,触发minorGCminorGC逐一检查eden区的对象是否有引用,没有引用的对象被清理掉。

小故事:

一个人(对象)出来(new 出来)后会在Eden Space(伊甸园)无忧无虑的生活,直到GC到来打破了他们平静的生活。GC会逐一问清楚每个对象的情况,有没有钱(此对象的引用)啊,因为GC想赚钱呀,有钱的才可以敲诈嘛。然后富人就会进入Survivor Space(幸存者区),穷人的就直接kill掉。

 

Survivor1(s1):

MinorGC后,从Eden活下来的对象被移动到survivor space(幸存区),当MinorGC再次扫描的时候,也会扫描survivor space中的对象,检查时候有引用,没有被清理,有就会被标记存货次数(经过了几次minorGC)。

小故事:

并不是进入Survivor Space(幸存者区)后就保证人身是安全的,但至少可以活段时间。GC会定期(可以自定义)会对这些人进行敲诈,亿万富翁每次都给钱,GC很满意,就让其进入了Old Gen(养老区)。万元户经不住几次敲诈就没钱了,GC看没有啥价值啦,就直接kill掉了。

 

Survivor1(s2):

survivors1)是一样的作用和原理,之所以要分12是为了保证堆中对象是在一个连续的内存中,防止内存的碎片化,提升程序效率。

S1S2还有一个名字from to ,s1s2交替作为fromto

s1from的时候s2就是to。当s1to的时候,s2就是from。(哪个幸存区是空的哪个就是to,反之有对象的幸存区叫from

每次minorGC清理完没有了引用的对象,都会把数据从from转移到to中(转移到to中的连续内存中),通过这种方式,防止了堆内存的碎片化。

 

Old:

当一个对象经过了多次的minorGC后,依旧存活(默认15GC,这个次数可配置),该对象将被转移到Old区(老年代)。

小故事:

进入到养老区的人基本就可以保证人身安全啦,但是亿万富豪有的也会挥霍成穷光蛋,只要钱没了,GC还是kill掉。

 

 

 

5,方法区(PermGen/永久代/Meta Space[java se 8])

 

方法区 是对 Permanet GenerationJVM规范里定义的标准名称

Java8开始,方法区被删除,开始使用metaSpace,并且metaSpace不再放在运行时数据区,而是放到了native memory,虽然以后再也看不到OOME:PermGen space 了,但是多了一个OOME:mata space 

 

它和堆一样是所有线程共享的。

存放了一些常量、静态变量、类信息等,可以理解成class文件在内存中的存放位置。

 

静态常量池(类,方法的内存模型)

所谓静态常量池,就是*.class中的常量池(每个class文件都有一个常量池),class文件中不仅包含代码中所定义的各种基本类型(如intlong等等)和对象型(如String及数组)的常量值,还包含一些以文本形式出现的符号引用,比如:

  类和接口的全限定名;

  字段的名称和描述符;

方法名称和描述符。

 

运行时常量池:

JVM完成类装载操作后,将nclass文件中的常量池载入到内存中,并保存在方法区中。我们常说的常量池,就是指方法区中的运行时常量池。

 

 

 

 

 


目录
相关文章
|
存储 安全 算法
深入剖析JVM内存管理与对象创建原理
JVM内存管理,JVM运行时区域,直接内存,对象创建原理。
40 2
|
1月前
|
存储 算法 安全
【JVM】深入理解JVM对象内存分配方式
【JVM】深入理解JVM对象内存分配方式
26 0
|
1月前
|
Java 程序员
探讨JVM垃圾回收机制与内存泄漏
探讨JVM垃圾回收机制与内存泄漏
|
25天前
|
存储 缓存 Java
金石原创 |【JVM盲点补漏系列】「并发编程的难题和挑战」深入理解JMM及JVM内存模型知识体系机制(1)
金石原创 |【JVM盲点补漏系列】「并发编程的难题和挑战」深入理解JMM及JVM内存模型知识体系机制(1)
34 1
|
25天前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
67 0
|
11天前
|
存储 前端开发 安全
JVM内部世界(内存划分,类加载,垃圾回收)(上)
JVM内部世界(内存划分,类加载,垃圾回收)
45 0
|
16天前
|
存储 算法 安全
深度解析JVM世界:JVM内存分配
深度解析JVM世界:JVM内存分配
|
1月前
|
存储 缓存 安全
[Java基础]——JVM内存模型
[Java基础]——JVM内存模型
|
1月前
|
存储 安全 Java
【JVM】Java堆 :深入理解内存中的对象世界
【JVM】Java堆 :深入理解内存中的对象世界
50 0
|
1月前
|
存储 Java 编译器
JVM虚拟机内存区域详情
JVM虚拟机内存区域详情
15 0

热门文章

最新文章