JVM002
1.到底什么是JVM的内存区域划分?
其实这个问题非常简单,JVM在运行我们写好的代码是,他是必须使用多块内存空间的,不同的内存空间
用来放不同数据,然后配合我们写的代码流程,才能让我们系统运行起来。
举个简单的例子,比如咱们现在知道了JVM会加载类到内存里来供后续运行,这些类加载到内存以后,
放到哪儿去了呢?所以JVM里就必须有一块内存区域,用来存放我们写的那些类。
【存放类的方法区】
这个方法区在JDK1.8以前的版本里,代表JVM中的一块区域。主要是放从.class文件里加载进来的类,
还会有一些类似常量池的东西放在这个区域里。但是在JDK1.8以后,这块区域的名字改了,叫做 metaspace,
可以认为是 元数据空间 这样的意思。当然这里主要还是存放我们自己写的各种类相关的信息。
大家首先明白一点:我们写好的java代码会被翻译成字节码,对应各种字节码指令
现在Java代码通过JVM跑起来的第一件事情就明确了,首先Java代码被编译成字节码指令,然后字节码指令一定
会被一条一条执行,这样才能实现我们写好的代码执行的效果。
所以当JVM加载类信息到内存之后,实际就会使用自己的字节码执行引擎,去执行我们写的代码编译出来的代码
指令,那么在执行字节码指令的时候,JVM里就需要一个特殊的内存区域了,那就是【程序计数器】
这个程序计数器就是用来记录当前执行的字节码指令的位置的,也就是记录目前执行到了哪一条字节码指令。
大家都知道JVM是支持多线程的,所以其实你写好的代码可能会开启多个线程并发执行不同的代码,所以就会
有多个线程来并发的执行不同的代码指令
因此每个线程都会有自己的程序计数器,专门记录当前这个线程目前执行到了哪一条字节码指令了
【java虚拟机栈】java代码在执行的时候,一定是线程来执行某个方法中的代码,但是在方法里面,我们经常定义
一些方法内的局部变量。因此,JVM必须有一块区域是来保存每个方法内的局部变量等数据的,这个区域就是
【Java虚拟机栈】。每个线程都有自己的java虚拟机栈,用来存放自己执行的那些方法的局部变量,
如果线程执行了一个方法,就会对这个方法调用创建对应的一个【栈帧】
栈帧里就有这个方法的局部变量表、操作数栈、动态连接、方法出口等东西。这里大家先不用全都理解,
我们先关注局部变量。在执行某个方法时,就会为该方法创建一个栈帧压入线程自己的java虚拟机栈里面去。
然后再栈帧的布局变量表里就会有局部变量。
【Java堆内存】Java中的对象实例都会存放在Java堆内存里
Java堆内存区域会放入对象,然后我们印在在方法中创建了对象,那么在线程执行方法的时候,就会在方法
对应的栈帧的局部变量表里,让一个引用类型的局部变量来存放对象的地址,相当于你可以认为局部变量表里的
某个变量指向了java堆内存里的对象
【其他内存区域】
其实在JDK很多底层API里,比如IO相关的,NIO相关的,网络Socket相关的 如果大家去看他内部的源码,
会发现很多地方都不是java代码了,而是走的native方法去调用本地操作系统里面的一些方法,可能调用的都是C语言
写的方法,或者一些底层类库
比如下面这样的 public native in hashCode();
在调用这种native方法的时候,就会有线程对应的本地方法栈,这个里面也是跟Java虚拟机栈类似的,也是存放各种
native方法的局部变量之类的信息。
还有一个区域,是不属于JVM的,通过NIO中的allocateDirect这种API,可以在Java堆外分给内存空间。然后,通过
Java虚拟机里的DirectByteBuffer来引用和操作堆外内存空间
其实很多技术都会用这种方式,因为有一些场景下,堆外内存分配可以提升性能。
根据周志明所著
根据Java虚拟机规范se7的规定,Java虚拟机所管理的内存将会包含以下几个运行时数据区域
【程序计数器】
【Java虚拟机栈】
【本地方法栈】 为虚拟机使用到的Native方法服务。有的虚拟机(HotSpot)直接就把本地房发展和虚拟机栈合二为一。
【Java堆】
【方法区】
【运行时常量池】 是方法区的一部分
【直接内存】并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。但是这部分内存也被
频繁地使用,而且也可能导致OutOfMemoryError异常出现。在JDK1.4中新加入了NIO类,引入了一种基于通道Channel和缓冲区
Buffer的IO方式,它可以使用native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存
的引用进行操作。这样能在一些场景中显著提高性能,因为避免了再Java堆和Native堆中来回复制数据。显然,本机直接内存的分配
不会收到Java堆大小的限制,但是,既然是内存,肯定还是会收到本机总内存(包括RAM以及SWAP区或者分页文件)大小以及处理器
寻址空间的限制。服务器管理员在配置虚拟机参数时,会根据实际内存设置-Xmx等参数信息,但经常忽略直接内存,是个各个内存区域
总和大于物理内存限制(包括物理和操作系统级的限制)从而导致动态扩展时出现OutOfMemoryError异常。

浙公网安备 33010602011771号