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\target\classes\com\imodule\dataImport\App.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

JVM基础详解的更多相关文章

  1. Dom探索之基础详解

    认识DOM DOM级别 注::DOM 0级标准实际并不存在,只是历史坐标系的一个参照点而已,具体的说,它指IE4.0和Netscape Navigator4.0最初支持的DHTML. 节点类型 注:1 ...

  2. [转]JVM指令详解(上)

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 本文主要记录一些JVM指令,便于记忆与查阅. 一.未归类系列A 此系列暂未归类. 指令码    助记符      ...

  3. Android中Canvas绘图基础详解(附源码下载) (转)

    Android中Canvas绘图基础详解(附源码下载) 原文链接  http://blog.csdn.net/iispring/article/details/49770651   AndroidCa ...

  4. javaScript基础详解(1)

    javaScript基础详解 首先讲javaScript的摆放位置:<script> 与 </script> 可以放在head和body之间,也可以body中或者head中 J ...

  5. Python学习一:序列基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7858473.html 邮箱:moyi@moyib ...

  6. Python学习二:词典基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...

  7. JVM内存详解-阅读笔记

  8. 深入浅出DOM基础——《DOM探索之基础详解篇》学习笔记

    来源于:https://github.com/jawil/blog/issues/9 之前通过深入学习DOM的相关知识,看了慕课网DOM探索之基础详解篇这个视频(在最近看第三遍的时候,准备记录一点东西 ...

  9. 三剑客基础详解(grep、sed、awk)

    目录 三剑客基础详解 三剑客之grep详解 1.通配符 2.基础正则 3.grep 讲解 4.拓展正则 5.POSIX字符类 三剑客之sed讲解 1.sed的执行流程 2.语法格式 三剑客之Awk 1 ...

随机推荐

  1. 【Postman】举例实战——天气查询

    准备工作: 1.下载postman(搜索官网下载即可) 2.接口文档(以聚合上去免费API:天气查询接口) 打开postman: 1.输入url 2.请求方式 3.请求参数 4.在postman中运行 ...

  2. 关于ajax请求不到后台页面提示400 bad request的问题

    解决方法一: 在contrller控制器中对应方法的 @RequestMapping注解中添加 method="RequestMethod.POST"属性

  3. 第1章 你好,C++并发世界

    #include<iostream> #include<thread> void print(){ std::cout << "hello world&q ...

  4. 蓝牙spp协议分析

    基本概念 蓝牙串口是基于 SPP 协议(Serial Port Profile),能在蓝牙设备之间创建串口进行数据传输的一种设备. 蓝牙串口的目的是针对如何在两个不同设备(通信的两端)上的应用之间保证 ...

  5. 【一起刷LeetCode】在未排序的数组中找到第 k 个最大的元素

    题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...

  6. HTML51-清除浮动overflow、网易注册界面基本结构搭建

    一.overflow:hidden;作用 (1)可以将超出标签范围的内容裁剪掉 (2)清除浮动 .box1{ background-color: red; /*border:1px white sol ...

  7. docker容器中安装vim 、telnet、ifconfig命令

    一.在使用docker容器时,有时候里边没有安装vim,敲vim命令时提示说:vim: command not found 问题:apt-get install vim安装vim 命令时,提示:如下内 ...

  8. ch-0503

    内容来源<算法竞赛进阶指南>date of submission:20191121tags:归排description modelling:你一定玩过八数码游戏,它实际上是在一个3*3的网 ...

  9. Java入门系列之集合LinkedList源码分析(九)

    前言 上一节我们手写实现了单链表和双链表,本节我们来看看源码是如何实现的并且对比手动实现有哪些可优化的地方. LinkedList源码分析 通过上一节我们对双链表原理的讲解,同时我们对照如下图也可知道 ...

  10. 读后感:数据结构与算法JavaScript描述

    本书看完,对常见的数据结构与算法从概念上有了更深入的理解. 书中关于数组.栈和队列.链表.字典.散列.集合.二叉树.图.排序.检索.动态规划.贪心算法都有详细的介绍.算是一本不错的学习书籍. 栈和队列 ...