jvm性能优化(一)-基于JDK1.8

简介: jvm性能优化(一)-基于JDK1.8

JVM的由来

①、类比计算机:

A、把jvm可以理解为一个计算机就可以了,为什么会称之为虚拟机呢?我们用到的电脑就是计算机,是实实在在的机器,而实的对立是虚,所以就有计算机,由于这个名字不好听,所以起名为虚拟机。

作用:平时的计算机是运行软件的,所以java虚拟机也应该是运行软件的

区别:实实在在的计算机是操作系统,什么软件都可以运行,而jvm只能够运行class文件软件系统的机器。通过jvm代替计算机的功能。

上面是通过计算机来类比的,可能无法了解内部的组件。

B、 jvm就是对实实在在的计算机上封装了而已,模拟计算机的功能,虚拟的东西,可以把jvm想象为软件而已。

C、上面的jvm是和计算机绑定的,当计算机系统升级的时候,这个jvm也应该升级,必须要适配更新的操作系统。如果jvm没有封装计算机的话,根本是垮不了平台。jvm是依赖操作系统实现的。

D、写的程序是存储在计算机的寄存器里面的。

②、类比后台的架构:

以业务为依据:后台的依据是前台的业务对象class文件。可以把数据库类比为内存。把后台架构类比为jvm,jvm也是有结构的。把前台的模型转换成后台的模型,最后把数据存储到内存,然后从内存中取出数据来使用。


jvm内存模型:

这是jvm整体的运行流程图,而在jvm虚拟机中主要的是三大块,java类加载器,运行时数据区,还有执行引擎。下面主要写运行时数据区的5个核心的组件。这5个核心组件在jvm调优的是时候很重要:

①、jvm的内存模型/结构

元数据空间,java堆,Java栈,本地方法栈,程序计数器

提出一个疑问:为什么叫做内存模型呢?

解释:因为不但把它们加载出来,还要存储,把这些数据存储到数据库,也就是存储到内存里面去,这些组件要存储到内存。所以把它叫做内存模型,可以把这5个的组件当成5张表来类比。

一、元数据空间

①、在jdk1.8之前是用方法区的(官方名字是永久代),而之后是用元数据空间代替的

元数据空间是一个抽象的概念,可以把它当成一张表,可以把元数据空间当作表。而表头就是存储的一些信息,除了表头还有数据,元数据空间里的数据,就是java定义的所有的类文件都放到内存。元数据空间就是发的java类,类文件的5种信息都需要存放:类名,父类,接口,属性(基本类型,复杂数据类型),方法,这5个是java类的标配。

②、我们写的类称之为资源,Java中用元数据描述资源,可以用注解@MXBean来描述一个元数据,这个java类变为class文件的一个元素:

  1. public class App extends App2 implements Demo
  2. {
  3.    // 定义常量
  4.    private final String name="2";

  5.    // 定义静态变量
  6.    private static String name11;

  7.    // 属性
  8.    private App3 app3;
  9.    private String name1;
  10.    private String name2;
  11.    private static App3 app5 = new App3();

  12.    public App(String name1){
  13.        this.name1 = name1;
  14.        this.name2= name2;
  15.    }

  16.    // 方法
  17.    public String demo(String name){
  18.        String name22 = "1";
  19.        String password = "2";
  20.        String password1 = "3"; // 保留记录行号

  21.        name22 = name22 + password;
  22.        app3 = new App3();
  23.        app3.demo();
  24.        synchronized (app3) {

  25.        }
  26.        app3.demo();// 方法的符号引用
  27.        System.out.println("222");
  28.        System.out.println("333");
  29.        return "";

  30.        // 对象如何调用?
  31.        // 对象该如何回收呢?
  32.        // 方法怎么执行?
  33.    }



  34.    public String demo1(){
  35.        System.out.println("222");
  36.        System.out.println("333");

  37.        return "";
  38.    }

  39.    public static void main( String[] args )
  40.    {

  41.        System.out.println( "Hello World!" );

  42.        for(int i = 0 ; i < 10000; i ++){
  43.            byte[] bs = new byte[1024 *1024 *10];
  44.        }


  45.    }

  46. }

③、在元数据空间里面存储的是类的所有的信息:元数据是描述数据的数据。

* 1、当前类名信息

*  2、字段信息

*  3、方法信息

*  4、父类信息

*  5、接口信息

*  6、引用信息(符号引用=====内存地址引用):类比spring中的Bean,先换成字符串,然后加载到内存。

*     6.1 类引引用信息(符号引用【一个字符串【类的权限定名】】=====内存地址引用)

    解释下符号引用:下面的是一个复杂的数据类型,而这个复杂的数据类型需要导入一个包,这是自定义的App3,可是在App这个类里面不认识这个程序,还没加载到内存中就把class文件看成是一个字符串。我们当引入包的时候可以看成是一个引用。

  1. privateApp3 app3;

*     6.2 方法引用信息(符号引用【一个字符串【方法描述符】】=====内存地址引用)

下面的图中的代码就可以称之为方法的引用,app3.demo():同样这个App的class文件不认识,第一次也会把它抽象成字符串。然后再加载到内存,分配相应的地址:

*     6.3 字段引用信息(符号引用【一个字符串【字段描述符】】=====内存地址引用)

这里只是做一个字符串的引用,而没有分配内存地址。

上面的过程可以类比 :数据库中的表来存储数据:存储数据的时候会返回一个id,地址就相当于是一个Id。可以理解一个表的增删改查。存储到内存的时候也是返回一个地址。数据库返回的是id,来标识这个数据。


*  7、常量信息:也是存储到元数据空间里面

  1. // 定义常量
  2. private final String name="2";

*  8、 静态变量信息:静态变量属于类对象的,类对象里的数据也会存储到元数据空间里面。

  1. // 定义静态变量
  2. privatestaticString name11;

注意:像下面的基本变量就不是存储到元数据空间里面的。字段多的话,会把字段来做一个抽象,方法也需要进行抽象,因为方法不知道有多少个,抽象出相同的规范。

*  9、classLoader引用

  class对象是由类加载器创建和加载的,类加载器也是对象,所以在元数据空间里面也有         classLoader的引用。

*  10、class 对象的实例

 整个类会转换成class文件,在反射中有一个class对象:getClass(),所以这个时候也会存储一个class对象的实例。

解释下永久代:不能变的东西就称之为永久代,存的数据是永久代,基本上是不会变的数据,类被加载成class文件是不可以修改的,更好听的名字就是元数据空间。


二、java堆:java堆也可以看成是一张表:

①、上面的是通过new关键字来创建的对象,创建对象的依据定义的的类来创建,因为元数据可以称之为所有数据的母数据,是所有子数据的母数据。都是由原数据扩展和延申的。

所以,第一步:将元数据所处的类的资源加载进来,

          第二步:然后再使用这个元数据进行set和get过程。

从元数据里面获取类引用信息,然后再进行创建,把App3动态的加载到java虚拟机之后

来进行创建对象

类名找到就可以获取到class文件,class文件加载到java虚拟机

②、app3=new App3():依赖的是符号引用,这个App3还没有加载进来。app3=new App3():会把这个元数据加载到java虚拟机,创建App3的实例,动态加载,把App3对象实例数据存到java堆里的,对象的值都放到堆里面的。属性的名存储在方法区,非类属性名在堆里的。


③、Java堆可以看成一张表,一张表中的一行就称之为一个对象

栈只是存储的是方法代码,存储方法里面的引用信息。

数据的引用在栈,指向堆,引用的地址信息存储在堆,值是存储在堆里的。

属性的符号引用是可以存储在方法区。

④、我们的对象还可以被锁住,锁的标识也会存储到堆中


类似hash,线程都是存储在堆里面的

以前是堆和元数据空间是在一起的,现在是分开的。


看下元数据空间和java堆,栈。

可以把元数据空间比喻成仓库,从仓库里面各有所需放到自己的空间里面去。执行数据的话是要依赖对象的数据,然后最后通过执行引擎来执行的。

元数据空间是存储所有的数据的。把值取出来放入到堆中。



三、java栈:

存可执行的字节码,就是方法内部的一些可执行的指令。把方法从元数据取出放到栈 里面的。方法存在java栈中,每个方法抽象出栈帧。下面栈中存储的信息:


*  1、本地变量表====(参数,局部变量)

*  2、操作数栈=====(参数值,局部变量值)

     有了变量之后还有值,操作数栈就是压入值和出入值的情况,操作数栈由值和指令组合。操作数栈里面存的都是值,由指令将这些值压入到操作数栈里面去。

*  3、动态链接=====(调用方法的符号引用,进行转换成内存地址)

*  4、返回地址=====(返回值)

*  5、其它信息

java栈的执行原理

上面勾起来的代码可以用下面的图解释:String name22="1";String password="2"3,String password1="3",是set的过程,就是压栈的过程,name22=name22+password:是get的过程,出栈。


四、本地方法栈:

java栈是一模一样的(就是调用c语言方法的  native,调用c语言的接口来实现)


五、程序计数器:

当在方法栈中执行 一段代码的时候:突然之间中断了cpu资源被另外一个线程给打断了

如何去保留这行的记录号呢?保留程序记录呢?

程序计数器:记录代码的执行行号:保留现场状态

当获取到cpu资源的时候会继续往下执行


GC:基本介绍(明天会详细写)

Gc(删除功能)===>类比:删除数据库的一张表的数据而已

*  1、什么对象需要收集

*    就是收集内存里面没有引用的对象定位

*  2、怎么去定位到对象没有被引用?

*    2.1 引用计数(存储在堆对象数据里面(对象头))

*      一个对象被引用一次,那么应用计数就加1,如果说没有引用,减1 引用计数等于0,就表示这个对象需要回收  

*  3、在什么时机下面Gc回收呢?  

*     3.1 新对象在创建的时候,内存空间不足的时候,开始Gc回收(删除对象实例),

*  4、特点(会中断所有的线程执行,降低程序响应速度)

由于算法不同,所以中断线程的时机不一样



内存组件包括:类加载器,运行时数据区(内存模型,执行引擎)

jvm的优化的地方就是优化运行时数据区的5个核心组件还有gc回收器

相关文章
|
18天前
|
SQL 缓存 监控
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
本文详细解析了数据库、缓存、异步处理和Web性能优化四大策略,系统性能优化必知必备,大厂面试高频。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
|
5月前
|
存储 Java 编译器
🔍深入Android底层,揭秘JVM与ART的奥秘,性能优化新视角!🔬
【7月更文挑战第28天】在Android开发中,掌握底层机制至关重要。从Dalvik到ART, Android通过采用AOT编译在应用安装时预编译字节码至机器码,显著提升了执行效率。ART还优化了垃圾回收,减少内存占用及停顿。为了优化性能,可减少DEX文件数量、优化代码结构利用内联等技术、合理管理内存避免泄漏,并使用ART提供的调试工具。
122 7
|
2月前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
3月前
|
存储 Java 编译器
🔍深入Android底层,揭秘JVM与ART的奥秘,性能优化新视角!🔬
【9月更文挑战第12天】在Android开发领域,深入了解其底层机制对提升应用性能至关重要。本文详述了从早期Dalvik虚拟机到现今Android Runtime(ART)的演变过程,揭示了ART通过预编译技术实现更快启动速度和更高执行效率的奥秘。文中还介绍了ART的编译器与运行时环境,并提出了减少DEX文件数量、优化代码结构及合理管理内存等多种性能优化策略。通过掌握这些知识,开发者可以从全新的角度提升应用性能。
68 11
|
4月前
|
存储 安全 Java
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别;什么是程序计数器,堆,虚拟机栈,栈内存溢出,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
|
5月前
|
Java 编译器 程序员
JVM常见面试题(一):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别
JVM常见面试题(一):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别
JVM常见面试题(一):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别
|
4月前
|
Java 编译器 测试技术
Java零基础教学(03):如何正确区别JDK、JRE和JVM??
【8月更文挑战第3天】Java零基础教学篇,手把手实践教学!
67 2
|
4月前
|
人工智能 Java 编译器
Java零基础(3) - 区别JDK、JRE和JVM
【8月更文挑战第3天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
74 1
|
4月前
|
缓存 Java 编译器
JRE、JDK、JVM 和 JIT 之间的区别详解
【8月更文挑战第22天】
147 0
|
5月前
|
Java 编译器 运维
开发与运维测试问题之在JVM中方法区也被称之为什么如何解决
开发与运维测试问题之在JVM中方法区也被称之为什么如何解决
24 1