JVM内存管理

2020-12-08  本文已影响0人  王多鱼2

以下内容:并非作者自己总结,勿喷


JVM.png

android大概了解这些
总结:JVM运行时数据区主要有 私有区域 java栈(先进后去,里面有N个栈帧) 本地栈(native栈), 程序计数器
共享区域 方法区: 存放 类信息 常量 静态变量 即时编译期编译后的代码
堆:new出来的对象

一:JVM是什么?

可以理解成只是一个翻译;
它可以跨平台,跨语音; 各种语言编译成字节码,然后通过JVM运行到各种平台上;

二:JVM的跨平台与语言无关性

JVM的跨平台
JVM的语言无关性

跨平台性.png

三:JVM的整体

JVM的整体.png

JVM的运行过程

java文件 --》javac翻译,生成class文件,通过类加载器classLoader,JVM会把class加载到运行时数据区(内存),在通过执行引擎
到操作系统上;

JVM就是把字节码翻译成机器码

四:什么是运行时数据区?

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域

它有如下类型

程序计数器、虚拟机栈、本地方法栈、Java堆、方法区(运行时常量池)、直接内存


运行时数据区域.jpg

线程私有区域

4.1 程序计数器

指向当前线程正在执行的字节码指令的地址

记录某个线程当前程序运行到那个位置;如图

4.1 .1:为什么需要这个程序计数器?

答:JVM是个软件,有可能程序在跑的时候,cpu被切换出去了(时间轮转机制),无论单线程还是多线程,有可能程序被终止,这个时候需要记录程序运行到哪一行;

4.1 .2:JVM内存区域中 唯一不会OOM ;

答: 因为它要记录一个地址;

运行内存区域.png

4.2 虚拟机栈(JAVA栈)

4.2.1:什么是栈帧?

java 解释执行是栈(操作数栈)兼容性好,效率偏低,c是寄存器(硬件运算)。移植性差

4.3 本地方法栈(native区)

本地方法栈保存的是native方法的信息,
本地方法栈跟 Java 虚拟机栈的功能类似,Java 虚拟机栈用于管理 Java 函数的调用,而本地方法栈则用于管理本地方法的调用。但本地方法并不是用 Java 实现的,而是由 C 语言实现的。

当一个JVM创建的线程调用native方法后,JVM不再为其在虚拟机栈中创建栈帧,JVM只是简单地动态链接并直接调用native方法

虚拟机规范无强制规定,各版本虚拟机自由实现 HotSpot直接把本地方法栈和虚拟机栈合二为一

线程共享的区域

4.4方法区

存放以下数据

4.4 堆(java堆)

Java堆的大小参数设置

-Xmx 堆区内存可被分配的最大上限
-Xms 堆区内存初始内存分配的大小

4.4:为什么共享区域不共用一个区域要分方法区和堆?

堆:对象和数组,频繁的回收;

直接内存

不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域;如果使用了NIO,这块区域会被频繁使用,在java堆内可以用directByteBuffer对象直接引用并操作;
这块内存不受java堆大小限制,但受本机总内存的限制,可以通过-XX:MaxDirectMemorySize来设置(默认与堆内存最大值一样),所以也会出现OOM异常。

五:从底层深入理解运行时数据区

image.png

上面代码内存分布图如下:


image.png

六:深入辨析堆和栈

功能角度:

线程独享还是共享:

空间大小

栈的内存要远远小于堆内存

六:内存溢出

七:虚拟机优化技术

编译优化技术——方法内联

image.png

方法内联的优化行为,就是把目标方法的代码原封不动的“复制”到调用的方法中,避免真实的方法调用而已。

栈的优化技术——栈帧之间数据的共享

在一般的模型中,两个不同的栈帧的内存区域是独立的,但是大部分的JVM在实现中会进行一些优化,使得两个栈帧出现一部分重叠。(主要体现在方法中有参数传递的情况),让下面栈帧的操作数栈和上面栈帧的部分局部变量重叠在一起,这样做不但节约了一部分空间,更加重要的是在进行方法调用时就可以直接公用一部分数据,无需进行额外的参数复制传递了。


image.png
上一篇下一篇

猜你喜欢

热点阅读