JVM探寻之旅:内存区域概述

目录

  • 前言
  • 正文
    • 一. JDK和JRE
    • 二. Java从编译到执行
    • 三. Java虚拟机
      • 运行时数据区
      • 直接内存
  • 后记

前言

人生中的第一篇博客,正好在学习架构课程,写博客是为了记录知识点方便自己以后复习巩固。由于本文是概述,所以大部分采用了周志明老师的《深入理解Java虚拟机》上的原文。

正文

一. JDK和JRE

我们可以把Java程序设计语言Java虚拟机Java类库这三部分统称为JDK(Java Development Kit),JDK是用于支持Java程序开发的最小环境。把Java类库API中的Java SE API子集Java虚拟机这两部分统称为JRE(Java Runtime Environment),JRE是支持Java程序运行的标准环境。JVM探寻之旅:内存区域概述_第1张图片

二. Java从编译到执行

JVM探寻之旅:内存区域概述_第2张图片

编译:一个Java 程序,首先经过javac编译成.class 文件。
加载:JVM将class文件加载到方法区,执行引擎将会执行这些字节码。
执行:翻译成操作系统相关的函数(机器码)。

三. Java虚拟机

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

Java虚拟机主要分为五大模块:类装载器子系统运行时数据区执行引擎本地方法接口垃圾收集模块

运行时数据区

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。运行时数据区可以分为两大类:线程私有区域(每个线程都会在虚拟机中分配一块单独的内存空间)和线程共享区域(被所有的线程共享,且只有一份)。而它们各自具体的划分如下:

线程私有(指令):程序计数器、虚拟机栈、本地方法栈
线程共享(数据):堆、方法区

JVM探寻之旅:内存区域概述_第3张图片

直接内存

JVM运行时会从操作系统申请大块的堆内存空间用于运行时数据的存储,同时还有虚拟机栈、程序计数器和本地方法栈内存(栈区),除此之外的本机剩余内存就叫直接内存(Direct Memory),亦可称之为堆外内存。它并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。
JVM探寻之旅:内存区域概述_第4张图片
在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区 (Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据(例如两个Java程序要互相通讯,都要经过直接内存,如果是保存在直接内存中就可以共享数据)。

直接内存不受Java堆大小的限制,但是受本机总内存(包括物理内存、SWAP分区或者分页文件)大小以及处理器寻址空间的限制,可以通过-XX:MaxDirectMemorySize来设置(默认与堆内存最大值一样)。

除了上述DirectByteBuffer引用堆外内存的方式外,其他堆外内存主要是使用了Unsafe和JNI方式直接申请的内存。

后记

本文是JVM学习的入门知识,简单概述了JVM内存空间的划分,在后续章节会详细介绍其中的运行时数据区。JVM官网地址:https://docs.oracle.com/javase/specs/index.html

你可能感兴趣的:(JVM,jvm)