zoukankan      html  css  js  c++  java
  • JVM基础详解

    JVM基础解析(一)

    Java里面有 JDK ,JRE, JVM ,这三者的关系是怎么样的呢?

    JDK是编译时环境: 整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库

    JRE是运行时环境: Java virtual machine(JVM),runtime class libraries和Java application launcher

    JVM是运行时环境:整个Java实现跨平台的最核心的部分,所有的Java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。

    JDK包含JRE,JRE包含JVM。

    关系如下图:

     

    JVM解析

    JVM内存结构如下图:(绿色标记的堆与方法区为线程共享区,所有线程安全问题都是从这儿引发的; 黄色标记区为线程独享区,和线程安全问题无关

    程序计数器(Program Counter),Java堆(Heap),Java虚拟机栈(Stack),本地方法栈(Native Stack),方法区(Method Area)

     

    >> 程序计数器(Program Counter)

      主要执行指令

      每个Java类编译后都会生成一个 *.class文件,例如我定义一个 App.java类,内容如下:

      App.java

    package com.imodule.dataImport;
    
    public class App {
    
    	public int add(){
    		int a = 11;
    		int b = 22;
    		int c = (a+b)*10;
    		return c;
    	}
    	
    	public static void main(String[] args) {
    		App app = new App();
    		int result  = app.add();
    		System.out.println("result = "+result);
    	}
    
    }

      生成的对应的App.class文件内容如下:(这些内容我们看不懂哈哈哈哈,所以下面会使用javap命令来分解)

      App.class

    漱壕   4 ;
     
     # $
      #
      %	 & ' (
      # )
      *
      +
      ,
     - . / <init> ()V Code LineNumberTable LocalVariableTable this Lcom/imodule/dataImport/App; add ()I a I b c main ([Ljava/lang/String;)V args [Ljava/lang/String; app result 
    SourceFile App.java   com/imodule/dataImport/App   0 1 2 java/lang/StringBuilder 	result =  3 4 3 5 6 7 8 9 : java/lang/Object java/lang/System out Ljava/io/PrintStream; append -(Ljava/lang/String;)Ljava/lang/StringBuilder; (I)Ljava/lang/StringBuilder; toString ()Ljava/lang/String; java/io/PrintStream println (Ljava/lang/String;)V !  
                 /     *??                              c     <=`
    h>?               
     	    *               	    
         	       q     '?Y?L+?=??Y??	?
    ???          
       
      &          '          
           !    "
    

       我们在windows打开cmd命令窗口,进入App.class文件存在的目录。(我的目录在这里: dataImport argetclassescomimoduledataImportApp.class ,其中开始的 dataImport是我的项目名)

         使用命令 javap -c App ,就会在下方输出指令信息

     

      我们可以用一个文件接收输出内容 ,这里将内内容存储在同级目录的 App.txt下

     

      最后 Apptxt文件中就会出现 程序计数器需要执行的指令啦(我们会发现指令是按大小顺序排列的,但是不是递增的)

      App.txt

    Compiled from "App.java"
    public class com.imodule.dataImport.App {
      public com.imodule.dataImport.App();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    
      public int add();
        Code:
           0: bipush        11
           2: istore_1
           3: bipush        22
           5: istore_2
           6: iload_1
           7: iload_2
           8: iadd
           9: bipush        10
          11: imul
          12: istore_3
          13: iload_3
          14: ireturn
    
      public static void main(java.lang.String[]);
        Code:
           0: new           #2                  // class com/imodule/dataImport/App
           3: dup
           4: invokespecial #3                  // Method "<init>":()V
           7: astore_1
           8: aload_1
           9: invokevirtual #4                  // Method add:()I
          12: istore_2
          13: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
          16: new           #6                  // class java/lang/StringBuilder
          19: dup
          20: invokespecial #7                  // Method java/lang/StringBuilder."<init>":()V
          23: ldc           #8                  // String result =
          25: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          28: iload_2
          29: invokevirtual #10                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
          32: invokevirtual #11                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          35: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          38: return
    }

     这里我们就来讲一下指令, add()方法里面的指令执行过程:

    public int add();
    Code:
    0: bipush 11   # 将常量 11 压入栈中 (当int取值-1~5采用iconst指令,取值-128~127采用bipush指令,取值-32768~32767采用sipush指令,取值-2147483648~2147483647采用 ldc 指令。)
    2: istore_1    # 将数值 11 从操作栈中取出,存储到局部变量 a
    3: bipush 22  # 将常量 22 压入栈中
    5: istore_2  # 将数值 22 从操作栈中取出,存储到局部变量 b
    6: iload_1   # 将局部变量 a 加载到操作栈
    7: iload_2   # 将局部变量 b 加载到操作栈
    8: iadd  # 执行加运算  局部变量a+b, 结果为33
    9: bipush 10 # 将常量10压入栈
    11: imul  # 执行乘运算,(a+b)*10,结果为 330
    12: istore_3 # 将计算结果 330从栈中取出,存储到局部变量 c
    13: iload_3 # 将局部变量 c 加载到操作栈
    14: ireturn # 将结果值返回

    >>Java堆(Heap) 先进先出

      存储对象

      实例变量、new出来的对象、数组等信息

       关于JVM内存的分配图:(其中永久代为方法区)

      堆内存中垃圾回收机制回收过程分析~

      首先对象会存储堆内存的 年轻代的 Eden区,

      进行垃圾回收后 存活的对象会移到 Survivor 去的 From, (From 和 To会一直有一个空间为空,用于来回复制存活对象 大概移动15~16次)

      存活的对象会进入老年代

      

      关于GC:

      虚拟机在进行MinorGC(新生代的GC)的时候,会判断要进入OldGeneration区域对象的大小,是否大于Old Generation剩余空间大小,如果大于就会发生Full GC。

      刚分配对象在Eden中,如果空间不足尝试进行GC,回收空间,如果进行了MinorGC空间依旧不够就放入Old Generation,如果OldGeneration空间还不够就OOM了。

      虚拟机中存在三种垃圾回收现象,minor GC、major GC和full GC。对新生代进行垃圾回收叫做minor GC,对老年代进行垃圾回收叫做major GC,同时对新生代、老年代和永久代进行垃圾回收叫做full GC。

    >>Java虚拟机栈(Stack) 后进先出 First in last out

      存储栈帧

      栈帧包括 局部变量表、操作栈、动态链接、方法出口

      方法存储在栈里面,一个方法对应一个栈帧。

      递归方法,就是自己调用自己,会有N个栈帧存储在栈中,且都符合后进先出的规则。 如果是个死循环就会出现栈溢出: Stackoverflow ................

    >>本地方法栈(Native Stack)

      JNI(Java Native Interface)

      本地方法栈,使用native修饰的方法,是指Java调用非Java代码的接口,方法是由非Java语言实现。

      DLL(Dinamic Link Library): 动态链接库文件

    >>方法区(Method Area)

      主要存放已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

      (比如spring 使用IOC或者AOP创建bean时,或者使用cglib,反射的形式动态生成class信息等)。

    ProcessOn绘图工具地址: https://www.processon.com/diagraming/5d254c70e4b0fdb331d8fa9e

  • 相关阅读:
    纠结我一上午的asp.net操作mysql问题
    C#术语【转自MSDN】
    asp.net新手必知必会——我们为什么要用asp.net
    图片在浏览器中底部对齐———解决方法之一
    asp.net做的网站比asp做的站慢?
    我是一个可悲的程序员
    今天离开职场去过自己的潇洒人生
    asp.net应用程序重新启动
    asp.net分页解决方法
    80. 删除有序数组中的重复项 II
  • 原文地址:https://www.cnblogs.com/DFX339/p/11162332.html
Copyright © 2011-2022 走看看