Table of Contents generated with DocToc

笔记来源:图灵学院

一、java虚拟机概述

  1. java虚拟机用于将字节码文件.class转化为不同操作系统上的机器码

  1. java虚拟机的内存模型


二、栈内存解析

2.1 概述

java虚拟机为每一个java线程分配一个栈内存空间,存放变量

  1. public class Math{
  2. public static final int initData = 666;//常量存储在方法区
  3. public int compute() { //一个方法对应一块栈帧内存区域
  4. int a=1;
  5. int b=2;
  6. int c = (a+b)*10;
  7. return c;
  8. }
  9. public static void main(String[] args){
  10. Math math = new Math();
  11. math.compute();
  12. }
  13. }

a,b,c 保存在main线程的compute()栈帧中

2.2 栈帧内部结构

学习栈帧内部结构前,我们首先要阅读字节码文件。

  1. javac Math.java
  2. javap -c Math.class > Math.txt

打开生成的Math.txt,可以看到反汇编后的代码如下:

  1. Compiled from "Math.java"
  2. public class jvm.Math {
  3. public static final int initData;
  4. public jvm.Math();
  5. Code:
  6. 0: aload_0
  7. 1: invokespecial #12 // Method java/lang/Object."<init>":()V
  8. 4: return
  9. public int compute();
  10. Code:
  11. 0: iconst_1
  12. 1: istore_1
  13. 2: iconst_2
  14. 3: istore_2
  15. 4: iload_1
  16. 5: iload_2
  17. 6: iadd
  18. 7: bipush 10
  19. 9: imul
  20. 10: istore_3
  21. 11: iload_3
  22. 12: ireturn
  23. public static void main(java.lang.String[]);
  24. Code:
  25. 0: new #1 // class jvm/Math
  26. 3: dup
  27. 4: invokespecial #25 // Method "<init>":()V
  28. 7: astore_1
  29. 8: aload_1
  30. 9: invokevirtual #26 // Method compute:()I
  31. 12: pop
  32. 13: return
  33. }
2.2.1 我们来解析一下compute()里面的代码:
  1. public int compute() { //一个方法对应一块栈帧内存区域
  2. int a=1;
  3. int b=2;
  4. int c = (a+b)*10;
  5. return c;
  6. }
  7. //=======================================
  8. public int compute();
  9. Code:
  10. 0: iconst_1 //将常量1压入操作数栈
  11. 1: istore_1 //将int类型的值存入局部变量1 -- a
  12. 2: iconst_2 //将常量2压入操作数栈
  13. 3: istore_2 //将int类型的值存入局部变量2 -- b
  14. 4: iload_1 //从局部变量1装载int类型的值
  15. 5: iload_2 //从局部变量2装载int类型的值
  16. 6: iadd //1+2
  17. 7: bipush 10
  18. 9: imul //*10
  19. 10: istore_3 //将int类型的值存入局部变量3 -- c
  20. 11: iload_3 //装载c的值
  21. 12: ireturn

赋值过程:

装载,执行过程(操作数栈:临时存储需要操作的值):

2.2.2 main函数内存区域

​ main中存储了一个math对象的指针,指向堆(堆中有为这个对象开辟的内存空间):

三、本地方法栈

早期 JAVA 需要与C/C++进行交互,所以用本地方法栈存储C/C++方法

四、堆

首先我们看看堆的结构:

​ 堆假设只有600M的话,那么年轻代占了1/3,也就是200M,老年代占了2/3。最开始的时候,对象都存放在Eden伊甸区)中。

​ 当Eden区装满时,则字节码执行引擎开启一个线程,运行minor gc,扫描伊甸区中的对象,如果对象被引用了,则在s0区中复制一份,否则留在Eden中,被垃圾回收机制清理。

​ 其他区域也是类似的处理(在Eden,s0,s1中移动时,“年龄“会加大,当达到15时,会转入老年区,controller、service、bean、数据库持久层、缓存都是常见的老年区对象):

​ 当老年代区放满后,字节码执行引擎开启一个线程,运行full gc,对所有区域进行垃圾回收,减少堆的空间,但是老年区被引用的对象还是不会被回收,所以当老年区再次被放满溢出时,会触发OutOfMemoryError的异常,即java堆不够用了。

扩展:STW【stop the world】,当 JVM 调用gc清理堆时,会暂停掉所有用户程序,比如电商购物时,点击按钮后通常会卡顿一下

垃圾回收,减少堆的空间,但是老年区被引用的对象还是不会被回收,所以当老年区再次被放满溢出时,会触发OutOfMemoryError的异常,即java堆不够用了。

扩展:STW【stop the world】,当 JVM 调用gc清理堆时,会暂停掉所有用户程序,比如电商购物时,点击按钮后通常会卡顿一下

所以 JVM 调优就是:尽量想方设法减少 STW 时间

图灵学院笔记-java虚拟机底层原理的更多相关文章

  1. Java虚拟机工作原理

    Java虚拟机工作原理 首先我想从宏观上介绍一下Java虚拟机的工作原理.从最初的我们编写的Java源文件(.java文件)是如何一步步执行的,如下图所示,首先Java源文件经过前端编译器(javac ...

  2. (前篇:NIO系列 推荐阅读) Java NIO 底层原理

    出处: Java NIO 底层原理 目录 1.1. Java IO读写原理 1.1.1. 内核缓冲与进程缓冲区 1.1.2. java IO读写的底层流程 1.2. 四种主要的IO模型 1.3. 同步 ...

  3. 理解java容器底层原理--手动实现HashMap

    HashMap结构 HashMap的底层是数组+链表,百度百科找了张图: 先写个链表节点的类 package com.xzlf.collection2; public class Node { int ...

  4. Java面试底层原理

    面试发现经常有些重复的面试问题,自己也应该学会记录下来,最好自己能做成笔记,在下一次面的时候说得有条不紊,深入具体,面试官想必也很开心.以下是我个人总结,请参考: HashSet底层原理:(问了大几率 ...

  5. Java虚拟机 - 结构原理与运行时数据区域

    http://liuwangshu.cn/java/jvm/1-runtime-data-area.html 前言 本来计划要写Android内存优化的,觉得有必要在此之前介绍一下Java虚拟机的相关 ...

  6. 阅读笔记--java内存模型原理

    在阅读本篇文章之前,我所理解的和上网了解到的java内存模型原理如下: 不同架构的物理计算机可以有不一样的内存模型,Java 虚拟机也有自己的内存模型.Java 虚拟机规范中试图定义一种 Java 内 ...

  7. Java虚拟机工作原理详解 ( 二 )

    首先这里澄清两个概念:JVM实例和JVM执行引擎实例,JVM实例对应了一个独立运行的Java程序,而JVM执行引擎实例则对应了属于用户运行程序的线程:也就是JVM实例是进程级别,而执行引擎是线程级别的 ...

  8. Java虚拟机工作原理详解 (一)

    一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 javac YourClassNam ...

  9. Java虚拟机工作原理详解

    原文地址:http://blog.csdn.net/bingduanlbd/article/details/8363734 一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了 ...

随机推荐

  1. Swagger之外的选择

    今天给大家安利一款接口文档生成器--JApiDocs. swagger想必大家都用过吧,非常方便,功能也十分强大.如果要说swaager有什么缺点,想必就是注解写起来比较麻烦.如果我说有一款不用写注解 ...

  2. SpringMVC 学习笔记(7)异常操作

    如何使用HandleException 在程序中,异常是最常见的,我们需要捕捉异常并处理它,才能保证程序不被终止. 最常见的异常处理方法就是用try catch来捕捉异常.这次我们使用springmv ...

  3. 如何下载 Ubuntu 镜像文件?

    Ubuntu,是一款基于 Debian Linux 的以桌面应用为主的操作系统,内容涵盖文字处理.电子邮件.软件开发工具和 Web 服务等,可供用户免费下载.使用和分享. 但是对于国内的用户来说如果直 ...

  4. python实现简单的SVM

    # -*- coding: utf-8 -*- from sklearn.svm import SVC import numpy as np print(X.shape,Y.shape) X = np ...

  5. dart快速入门教程 (2)

    2.变量和数据类型 2.1.变量和常量 变量通俗的说就是可以变化的量,作用就是用来存储数据,你可以把一个变量看作是一个水果篮,里面可以装苹果.梨.香蕉等,常量就是一个固定的值,和变量是相对的,变量可以 ...

  6. vs2017,vs2019 无法连接到Web服务器“IIS Express”

    不知道啥原因,突然就不能访问了 我的解决方式: 在项目的根目录下显示所有隐藏的文件,找到.vs文件夹,删除: 重启项目,尝试运行,发现正常了. (完)

  7. 关于位图数据和标记位-P3

    文章目录 1 背景 1.1 问题 2 问题1探究 2.1 没有区的情况 2.2 一个区的情况 2.3 两个区的情况 2.4 三个区的情况 2.5 四个区的情况 2.6 五个区的情况 3 问题2探究 3 ...

  8. Spring Boot -- 启动流程分析之ApplicationContext 中

    上一节我们已经分析到AbsractApplicationContext类refresh方法中的postProcessBeanFactory方法,在分析registerBeanPostProcessor ...

  9. c语言学习笔记第三章———数据和C

    B站有视频演示 本章将会讲解c语言的数据定义和使用,您将会了解int.float.double.char的含义,了解命名的规则,对c语言会有更加深刻的认识. 变量命名: 我们先讲上次视频没讲的变量命名 ...

  10. TensorFlow中的显存管理器——BFC Allocator

    背景 作者:DeepLearningStack,阿里巴巴算法工程师,开源TensorFlow Contributor] 使用GPU训练时,一次训练任务无论是模型参数还是中间结果都需要占用大量显存.为了 ...