关于Java虚拟机二三事(一)---Java技术体系及JVM内存结构

2024-08-23 01:58

本文主要是介绍关于Java虚拟机二三事(一)---Java技术体系及JVM内存结构,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

作为一个爱好Java的程序猿,自然少不了对JVM的学习和研究,《深入理解Java虚拟机》一书,大概从头到尾完整地看了四五遍,有些地方感觉讲的粒度比较粗,但只是少数,总体而言,这本书讲解的非常棒,不少东西都是看了第二次,甚至第三次之后才有了进一步的理解。

走进Java-Java技术体系

从广义上讲,Clojure、JRuby、Groovy等运行于Java虚拟机上的语言及其相关程序都属于Java技术体系中的一员。但是,如果仅从传统意义上看,Sun官方所定义的Java 技术体系包括以下几个组成部分。

  • Java程序设计语言
  • 各种硬件平台上的Java虚拟机
  • Java API类库
  • Class文件格式
  • 来自商业机构及开源社区的第三方Java类库

    这里,还可以进一步细分,
    Java体系

      其中,JVM(Java Virtual Machine,Java虚拟机)可以说是支撑整个Java技术体系运行的关键所在。下图是Java虚拟机的整体结构,主要描述的是从编写好的Java代码(.java文件),经过编译器编译形成字节码文件(.class文件),字节码文件通过类加载器加载到运行时数据区中,并由执行引擎按照代码执行顺序逐步执行。

    Java虚拟机

      不同于C/C++,Java程序员将内存控制的权力交给了Java虚拟机,因此,为了能够更好的了解虚拟机对内存的使用,以及对内存泄漏和溢出等方面问题的定位,有必要深入理解Java虚拟机的内存管理机制。

      而Java虚拟机最主要的内存区域,便是运行时数据区,也就是下图中红色箭头所指的区域(Runtime Data Areas)。

运行时数据区

  这部分区域,便是Java程序在运行时,所有涉及的变量、方法、对象存储的地方。我们可以通过下图更进一步了解运行时数据区的内部结构划分。
  
运行时数据区结构

从上图可知,运行时数据区总共分为5部分:方法区、虚拟机栈、本地方法栈、堆、程序计数器。下面将简单介绍一下各部分在运行时数据区中的主要作用。后续将做进一步的详细介绍。
  1.程序计数器:
  程序计数器是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器,如果了解计算机处理器内部结构的同学,其实可以很容易理解,处理器中会有32个32位的寄存器,寄存器是用来进行各类计算的基本单元,而程序计数器本质便是一个32位的寄存器,它存放的是当前字节码执行的行号,同时利用程序计数器,也能够定位到下一句即将执行的语句。
   又因为Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,因此在任何一个确定的时刻,一个处理器都只会执行一条线程。因此,为了线程切换后能够恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。
   2.Java虚拟机栈:
   与程序计数器一样,虚拟机栈也是线程私有的,虚拟机栈主要描述的是Java方法执行的内存模型,每个方法在执行的同时,会创建一个栈帧,每个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口信息等。而方法从调用到完成的阶段,就是入栈到出栈的过程。
   3.本地方法栈:
   本地方法栈与虚拟机栈的作用非常相似,他们之间区别不过是虚拟机栈为虚拟机执行Java方法提供服务,而本地方法栈则是为虚拟机使用到的Native方法服务。
   4.Java堆:
   对于大多数应用来说,Java堆是Java虚拟机中所管理内存中最大的一块,因为Java堆中存放了所有的对象实例和数组。且Java堆被所有线程所共享,在虚拟机启动的时候会自动创建,这块区域也是垃圾回收时的重点区域。
   5.方法区:
   方法区与Java堆一样,被各个线程所共享内存,它用于存储虚拟机加载的类信息、常量、静态变量、即时编译器变异后的代码等数据。这里需要额外提及的是运行时常量池,它是方法区的一部分,Class文件中除了存放类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译阶段生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

          

这篇关于关于Java虚拟机二三事(一)---Java技术体系及JVM内存结构的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1098033

相关文章

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

Ubuntu固定虚拟机ip地址的方法教程

《Ubuntu固定虚拟机ip地址的方法教程》本文详细介绍了如何在Ubuntu虚拟机中固定IP地址,包括检查和编辑`/etc/apt/sources.list`文件、更新网络配置文件以及使用Networ... 1、由于虚拟机网络是桥接,所以ip地址会不停地变化,接下来我们就讲述ip如何固定 2、如果apt安

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

springboot将lib和jar分离的操作方法

《springboot将lib和jar分离的操作方法》本文介绍了如何通过优化pom.xml配置来减小SpringBoot项目的jar包大小,主要通过使用spring-boot-maven-plugin... 遇到一个问题,就是每次maven package或者maven install后target中的ja

Java中八大包装类举例详解(通俗易懂)

《Java中八大包装类举例详解(通俗易懂)》:本文主要介绍Java中的包装类,包括它们的作用、特点、用途以及如何进行装箱和拆箱,包装类还提供了许多实用方法,如转换、获取基本类型值、比较和类型检测,... 目录一、包装类(Wrapper Class)1、简要介绍2、包装类特点3、包装类用途二、装箱和拆箱1、装