全面了解JVM原理与深度调优

本文详细探讨了Java虚拟机(JVM)的工作原理,包括内存结构、类加载器、执行过程、垃圾回收机制及算法。JVM内存分为堆、栈、本地方法栈、方法区等多个区域,每个区域都有其特定的功能。类加载器负责加载类文件,而JMM(Java内存模型)确保线程安全。垃圾收集器如CMS和Serial等管理内存分配和回收,以避免内存溢出。通过调整JVM参数,如-Xms和-Xmx,可以优化堆内存的分配。此外,JVM的垃圾收集策略,如复制算法和标记-清除算法,对于性能调优至关重要。
摘要由CSDN通过智能技术生成

什么是jvm


jvm是java虚拟机 运行在用户态、通过应用程序实现java代码跨平台、与平台无关、实际上是"一次编译,到处执行"

1.从微观来说编译出来的是字节码!去到哪个平台都能用,只要有那个平台的JDK就可以运行!字码好比是一个人,平台好比为国家,JDK好比这个国家的语言!只要这个人(字节码)有了这个国家的语言(JDK)就可以在这个国家(平台)生活下去。
2.JDK 是整个Java的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具和Java基础的类库(rt.jar)。
3.Java虚拟机(JVM)一种用于计算机设备的规范,可用不同的方式(软件或硬件)加以实现。编译虚拟机的指令集与编译微处理器的指令集非常类似。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。
4.java编译出来的是一种“java字节码”,由虚拟机去解释执行。而c和c++则编译成了二进制,直接交由操作系统执行。
5.所谓的一次编译、到处执行,即只需在一个地方编译,在其他各个平台下都可以执行。
6.与平台无关指的是JAVA只运行在自己的JVM上,不需要依赖任何其他的底层类,所以和操作系统没有任何联系,平台是说运行的系统

内存结构图

 class文件

class文件径打破了C或者C++等语言所遵循的传统,使用这些传统语言写的程序通常首先被编译,然后被连接成单独的、专门支持特定硬件平台和操作系统的二进制文件。通常情况下,一个平台上的二进制可执行文件不能在其他平台上工作。而Java class文件是可以运行在任何支持Java虚拟机的硬件平台和操作系统上的二进制文件。

执行过程

 执行过程简介

当编译和连接一个C++程序时,所获得的可执行二进制文件只能在指定的硬件平台和操作系统上运行,因为这个二进制文件包含了对目标处理器的机器语言。而Java编译器把Java源文件的指令翻译成字节码,这种字节码就是Java虚拟机的“机器语言”。

与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。

JVM中的ClassLoader

JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,BootstrapClassLoader是用本地代码实现的,它负责加载核心JavaClass(即所有java.*开头的类)。

另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由BootstrapClassLoader加载;其中Extension ClassLoader负责加载扩展的Javaclass(例如所有javax.*开头的类和存放在JRE的ext目录下的类)ApplicationClassLoader负责加载应用程序自身的类。

当运行一个程序的时候,JVM启动,运行bootstrapclassloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。

第一个Class文件、通过javac编译成字节码、字节码之后有个ClassLoader叫类加载器,因为java.class文件到JVM内部运行起来需要有个装载过程、从物理的文件到内存的结构、比如加载、连接、初始化。

linux应用程序有个进程地址空间,对进程地址空间的解释:

linux采用虚拟内存管理技术,每一个进程都有一个3G大小的独立的进程地址空间,这个地址空间就是用户空间。每个进程的用户空间都是完全独立、互不相干的。进程访问内核空间的方式:系统调用和中断。
创建进程等进程相关操作都需要分配内存给进程。这时进程申请和获得的不是物理地址,仅仅是虚拟地址。 
实际的物理内存只有当进程真的去访问新获取的虚拟地址时,才会由“请页机制”产生“缺页”异常,从而进入分配实际页框的程序。该异常是虚拟内存机制赖以存在的基本保证,它会告诉内核去为进程分配物理页,并建立对应的页表,这之后虚拟地址才实实在在的映射到了物理地址上。

Linux操作系统采用虚拟内存技术,所有进程之间以虚拟方式共享内存。进程地址空间由每个进程中的线性地址区组成,而且更为重要的特点是内核允许进程使用该空间中的地址。通常情况况下,每个进程都有唯一的地址空间,而且进程地址空间之间彼此互不相干。但是进程之间也可以选择共享地址空间,这样的进程就叫做线程。

基本上所有linux应用程序都会遵循这个规泛、有栈、有堆、对于JVM来说、也是遵循这个规则、只不过在这个规则上做了一些改进

通过类加载器把Class文件装载进内存空间、装进来以后只是你的字节码,然后你需要去运行、怎么去运行呢 ?图中类加载器子系统下面都是运行区
内存空间里有:
1.方法区:被装载的class的信息存储在Methodarea的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件内容并把它传输到虚拟机中。
2.Heap(堆):一个Java虚拟实例中只存在一个堆空间。
3.JavaStack(java的栈):虚拟机只会直接对栈执行两种操作:以帧为单位的压栈或出栈,java栈有个核心的数据、先进后出
4.Nativemethodstack(本地方法栈):通过字面意思、基本是调用系统本地的一些方法、一般在底层封装好了、直接调用
5.地址、在这里边是一个指针的概念、比如从变量到对象怎么做引用、就是地址
6.计数器:主要做字节码解析的时候要记住它的位置、可以理解为一个标记
7.执行引擎:数据、字节码做一些业务处理、最终达到想要的结果
8.本地方法接口:基本是底层系统、比如IO网络、调用操作系统本身
9.本地方法库:为了兼容、实现跨平台有不同的库 、兼容平台性
额外数据信息指的是本地方法接口和本地方法库

JMM

java的内存模型

大家可能听过一个词、叫线程安全、在写高并发的时候就会有线程安全问题、java里边为什么会出现线程安全问题呢、因为有JMM的存在、它会把内存分为两个区域(一个主内存、一个是工作内存)工作内存是每个java栈所私有的
因为要运行速度快、需要把主内存的数据放到本地内存中、然后进行计算、计算完以后再把数据回显回去

JMM有两个区域、主内存和栈内存、
java

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值