JVM知识(上)

目录

  • 什么是JVM?
  • JVM的生命周期
  • JVM的体系结构
  • JVM的数据类型

java虚拟机被称为“虚拟”,因为它是一个抽象的计算机定义的规范。要运行一个Java程序,需要一个抽象的规范的具体实现。以下内容主要还是参考《Inside JVM》

什么是JVM?

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM三种不一样的地方:抽象的规范,一个具体的实现,运行时的实例。

JVM的生命周期

java虚拟机种运行的一个实例有着明确的“使命”:运行一个java程序,当程序启动时,产生一个运行实例,当程序运行完成时,实例就没了。如果同时启动三个java程序,在同一台电脑上,使用相同的实现方法,你就会得到三个java虚拟机的实例,每个java程序运行在自己的虚拟机实例上面。

Java虚拟机实例通过调用一些初始类的main()方法来开始运行其单独应用程序,该main()方法必须时公共(public),静态(static),无返回值的(void),并且接受一个字符串数组的参数(String[] args),按照上面定义的main()方法,任何一个类的main方法都可以作为程序启动的起点。


public class Application {
      public static void main(String[] args) {
         SpringApplication.run(Application.class, args);
      }
}

在java虚拟机中,线程分两种:守护线程(daemon,也可以成为后台线程)和 非守护线程(non-daemon,前台线程)。


daemon守护线程是JVM自己用的,就比如我们常说的垃圾回收。non-daemon非守护线程,应用程序启动了main(),然后再调用我们自己写的方法。

一个java程序在运行时,只要非守护线程一直运行,那么java虚拟机实例就一直存在,当所有的java非守护线程中断时,java虚拟机实例也就消失了。当然我们也可以直接通过类Runtime或者类System调用exit()方法来使程序中断。

JVM的体系结构

在java虚拟机规范中,java虚拟机的行为是由子系统,内存区域,数据类型和指令来描述的。这些组件的目的与其说是决定内部架构的实现,更提供了一种严格定义的外部行为的实现。规范定义了所需的任何Java虚拟机的行为来实现这些抽象组件及其之间的交互。

一个Java虚拟机,包括主要的子系统和内存区域中描述的规范如前一章中提到,每个Java虚拟机有一个类装入器子系统:加载机制类型(类和接口)指定完全限定的名称。每个Java虚拟机还提供一个执行引擎:一种机制负责执行的指令包含在加载的类的方法。

当一个Java虚拟机运行一个程序的时候,他需要内存存储更多的东西,包括直接码和其它信息摘录加载类文件,程序实例化对象,参数方法,返回值,局部变量,计算的中间结果。虽然相同的数据区域运行在每一个java虚拟机的实现上,规范是抽象的,但具体运行这些数据区域的细节的时候还是需要(设计者)实现者来具体实现。

不同的java虚拟机的实现有很多不同的内存限制,有些实现需要很多的内存为其工作,而有的实现却需要的很少;有的实现可以利用java虚拟内存,有的却不可以;运行时数据区域的抽象性质规范更容易在各种各样的电脑和设备实现Java虚拟机。

一些运行时的数据区被一个程序线程或者其它独一无二的线程所共享,每一个java虚拟机实例都有一个方法区(method area)和堆(heap)。这些区域内运行的所有线程共享虚拟机。当JVM加载一个类文件(class文件)时,JVM会从二进制数据中解析出包含信息类型的类文件。它会把这些类的文件送到方法区里面去。当程序运行时,虚拟机将所有对象实例化到堆(heap)。

因为每个新线程启动,它有自己的电脑注册(程序计数器)和Java堆栈。如果线程正在执行Java方法(不是一个本地方法),pc寄存器的值显示为要执行下一个指令。Java堆中存储着Java线程(非原生)方法调用的状态。Java方法调用的状态包括局部变量、被调用的参数,它的返回值(如果有的话),中间的计算。本地方法调用的状态以具体实现相关的方式在本地方法栈存储着,以及可能在寄存器或其他具体实现相关的内存区域。Java堆栈由堆栈帧(帧)组成。一个堆栈帧包含一个Java方法调用的状态,说白了就是每个栈就是一个每个调用的方法。当一个线程调用一个方法时,Java虚拟机会分配一个新的栈给那个线程的方法。当方法完成时,虚拟机就会丢弃此方法的栈。Java虚拟机没有寄存器来保存中间数据值。指令集被使用在Java堆栈存储这些中间数据值。

上图中,线程1和2是执行java方法,线程3 执行本地的方法。

JVM的数据类型

Java虚拟机通过操作某些类型的数据来进行计算。这些数据类型和操作都严格定义的Java虚拟机规范。可以分为一组基本类型和引用类型。变量的原始类型保存原始值,变量的引用类型值的引用。引用值引用对象,但不是对象本身。原始值,相比之下,不参考任何东西。他们是实际数据本身。

所有原始类型的Java编程语言,除了布尔类型,其它都是是Java虚拟机的基本类型。编译器将Java源代码转换为字节码时,它使用int或字节来表示布尔值。在Java虚拟机中,错误的是由整数0和真正的任何非零的整数,业务涉及到布尔值使用int。布尔访问数组作为字节数组,尽管它们可能在堆上表示为字节数组或字段。原始类型的Java编程语言以外的布尔形成了数字类型的Java虚拟机。之间的数值类型为: byte, short, int, long, , char。与Java编程语言一样,Java虚拟机的基本类型有相同的范围。长在Java虚拟机总是像一个64位表示整数,独立于底层主机平台。Java程序员可以使用适用于Java虚拟机而不在原始类型中的returnValue类型。这种原始的类型在Java程序被使用。引用类型分为三种:类类型,接口类型和数组类型。所有三种类型值对动态创建对象的引用。class type值对类实例的引用。array type值是数组的引用,这是成熟的对象在Java虚拟机。interface type值是实现一个接口的类实例的引用。另一个值是null值的引用,这表明没有引用任何对象的引用变量。Java虚拟机规范定义了每个数据类型的值的范围,但没有定义他们的大小。bits比特数用来存储每个数据类型。

下篇将详细介绍JVM中heap,stack,method area如何工作的

原文地址:https://www.cnblogs.com/levcon/p/9502008.html

时间: 2024-10-18 19:57:24

JVM知识(上)的相关文章

android金阳光自动化测试——学习历程:自动化预备知识上&&下

章节:自动化基础篇——自动化预备知识上&&下 网易云课堂: 上:http://study.163.com/course/courseLearn.htm?courseId=712011#/learn/video?lessonId=877113&courseId=712011 下:http://study.163.com/course/courseLearn.htm?courseId=712011#/learn/video?lessonId=877114&courseId=71

JVM 线上故障排查基本操作--CPU飙高

JVM 线上故障排查基本操作 CPU 飚高 线上 CPU 飚高问题大家应该都遇到过,那么如何定位问题呢? 思路:首先找到 CPU 飚高的那个 Java 进程,因为你的服务器会有多个 JVM 进程.然后找到那个进程中的 “问题线程”,最后根据线程堆栈信息找到问题代码.最后对代码进行排查. 如何操作呢? 通过 top 命令找到 CPU 消耗最高的进程,并记住进程 ID. 再次通过 top -Hp [进程 ID] 找到 CPU 消耗最高的线程 ID,并记住线程 ID. 通过 JDK 提供的 jstac

JVM 线上故障排查基本操作

# 前言 对于后端程序员,特别是 Java 程序员来讲,排查线上问题是不可避免的.各种 CPU 飚高,内存溢出,频繁 GC 等等,这些都是令人头疼的问题.楼主同样也遇到过这些问题,那么,遇到这些问题该如何解决呢? 首先,出现问题,肯定要先定位问题所在,然后分析问题原因,再然后解决问题,最后进行总结,防止下次再次出现. 今天的文章,就如我们的题目一样,讲的是基本操作,也就是一些排查线上问题的基本方法.为什么这么说呢?因为线上问题千奇百怪,就算是身经百战的专家也会遇到棘手的问题,因此不可能在一篇文章

JVM系列(七) - JVM线上监控工具

前言 通过上一篇的 JVM 垃圾回收知识,我们了解了 JVM 具体的 垃圾回收算法 和几种 垃圾回收器.理论是指导实践的工具,有了理论指导,定位问题的时候,知识和经验是关键基础,数据可以为我们提供依据. 在线上我们经常会遇见如下几个问题: 内存泄露: 某个进程突然 CPU 飙升: 线程死锁: 响应变慢. 如果遇到了以上这种问题,在 线下环境 可以有各种 可视化的本地工具 支持查看.但是一旦到 线上环境,就没有这么多的 本地调试工具 支持,我们该如何基于 监控工具 来进行定位问题? 我们一般会基于

【JVM 知识体系框架总结】

JVM 内存分布 线程共享数据区: 方法区->类信息,静态变量 堆->数组对象 线程隔离区 虚拟机栈-> 方法 本地方法栈->本地方法库 native 堆.程序计数器 JVM 运行数据 程序计数器 线程隔离 ,比较小的内存空间,当前线程所执行的字节码的行号 线程是一个独立的执行单元,由 CPU执行 唯一没有 OOM 的地方,由虚拟机维护,所以不会出现 OOM 虚拟机栈 执行的是Java方法 方法的调用就是栈帧入虚拟机栈的过程 栈帧:局部变量表(变量) .操作数栈(存放a+b的结果

[转帖]【JVM 知识体系框架总结】

https://www.cnblogs.com/mousycoder/p/11612448.html JVM 内存分布 线程共享数据区:方法区->类信息,静态变量堆->数组对象 线程隔离区虚拟机栈-> 方法本地方法栈->本地方法库 native 堆.程序计数器 JVM 运行数据 程序计数器 线程隔离 ,比较小的内存空间,当前线程所执行的字节码的行号线程是一个独立的执行单元,由 CPU执行唯一没有 OOM 的地方,由虚拟机维护,所以不会出现 OOM 虚拟机栈 执行的是Java方法 方

刚从京东面试回来,我才知道这些JVM知识有多重要

面试题关于JVM的知识之前也写过相关的文章整理,但是从京东面试后,才发现这些JVM的知识点尤为重要,所以特意整理出来以供大家参考.1.什么是类的加载?2.哪些情况会触发类的加载?3.讲一下JVM加载一个类的过程4.什么时候会为变量分配内存?5.JVM的类加载机制是什么?6.双亲委派机制可以打破吗?为什么答案放在文章的最后,来不及看原理也可以直接跳到最后直接看答案.深入原理类的生命周期类的生命周期相信大家已经耳熟能详,就像下面这样:不过这东西总是背了就忘,忘了又背,就像马什么梅一样,对吧?其实理解

JVM知识学习与巩固

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的. 我们运行和调试Java程序的时候,经常会提到一个JVM的概念.JVM是Java程序运行的环境,但是他同时一个操作系统的一个应用程序一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间. 以下转自:http://blog.csdn.net/ning109314/article/details/10

概率论机器学习的先验知识(上)

随着Hadoop等大数据的出现和技术的发展,机器学习越来越多地进入人们的视线. 其实早Hadoop之前,机器学习和数据挖掘已经存在,作为一个单独的学科,为什么hadoop之后出现,机器学习是如此引人注目了?因是hadoop的出现使非常多人拥有了处理海量数据的技术支撑.进而发现数据的重要性,而要想从数据中发现有价值的信息.选择机器学习似乎是必定的趋势.当然也不排除舆论的因素.事实上本人一直对非常多人宣称掌握了机器学习持怀疑态度.而要想理解机器学习的精髓.数学知识是不可或缺的,比方线性代数.概率论和