(.class字节码)类加载到内存之后,内存模型:(ps:.class文件可以通过javap 指令反编译成一个可读文件)

1.java栈,本地方法栈,程序计数器(每个线程私有)

看如下程序:

以该程序为例,运行该程序,jvm会分配给该程序一个线程,总体图示如下:

该线程在运行时候,java虚拟机会分配给该线程独立的java栈,而栈帧存在于栈中,存放的是 每一个方法运行时候需要的数据(每一个方法都有一个栈帧,栈帧存的是 局部变量表,操作数栈,动态链接,方法出口),上图有两个方法,即 jvm会分配两个栈帧。

首先入栈的是main方法的栈帧,当main方法new一个math对象时候,该栈帧当中存放了math的引用,而math对象是放在堆中,方法区中会放置Math类的.class文件,一些类的静态变量和常量也会放入方法区,比如:

然后main方法中调用了math方法(new了一个math对象),从而math方法的栈帧入栈,当math方法执行完毕之后,它的栈帧会弹出栈。

(使用javap指令反编译一下 Math.class)

查询jvm指令可知:iconst_1的含义是

(栈即使 操作数栈),istore_1的含义是

iconst_2,istore_2也一样。对应 int a=1 ;int b=2;

程序计数器也是每一个线程私有的,每个方法运行的时候,都有一个程序计数器,作用是告诉jvm接下来该运行哪一行代码,即是一个指针,如反编译后图的0,1,2,3......前四行代码都执行了,现在该运行4, 程序计数器放的内容是4

然后,执行int c=(a+b)*10,对应 iload_1,iload_2 ,含义如下,

对应结果(从局部变量表 装载到 操作数栈,PS:局部变量表中的值还在,只是复制到操作数栈中,下图显示不正确)

接着计算a+b,对应的是将b=2,a=1都弹出栈,进行+运算,然后将算出的结果3,放入操作数栈中,然后需要10,所以将10也压入栈

执行3*10的操作,需要将3和10均弹出栈进行乘的计算,计算的出30,再压回操作数栈中,然后将30弹出栈,进入局部变量表:

最后math方法执行方法执行完毕,会通过方法出口返回给main方法,并且,math方法的栈帧主动弹出栈销毁

本地方法栈是存放程序调用的native方法,(或者程序底层的native方法)

有个结论:java栈,本地方法栈,程序计数器是每一个线程私有的,而堆和方法区是所有线程所共享的。(堆和方法区共享是因为,其他线程也能创建相同的对象,比如math,也要用到方法区的一些内容)

附上两幅图:

2.堆和方法区的介绍(线程共享)

包括 新生代,老年代,元空间(MetaData space),(ps:方法区实际上不存在,只是一个逻辑上的概念,而元空间或者永久代<jdk 1.8之前>是方法区的具体代码实现)

老年代是新生代空间的两倍。

当程序创建对象的时候,对象会首先进入新生代的Eden中,如果新生代的Eden空间满了,Jvm会进行一些小GC,将一些没有引用指向的对象,即垃圾对象清除掉。其他的不能GC的对象(即还有引用指向的对象)会被移到Suvivor区域,如果第一个Suvivor区(From)也满了,也会进行GC,GC之后,会将第一个Suvivor剩下的所有对象复制到第二个Suvivor区域(To)。

程序如果继续创建对象,会继续对Eden GC,这时候,其他不能GC的对象会被移到Survivor第二个区域中(To区域),第二个区域和第一个区域角色互换,重复上面操作,然后再一轮角色又互换。这样经过好几轮.........................................

如果JVM这样好几次操作(JDK1.8默认15次,也可设置)之后,还有些对象没有被GC,这些对象会被放入老年代Old Generation。如果程序再创建对象,新生代和老年代都满了,JVM会对老年代进行一次full GC,清楚无效的对象,Full GC可能会使JVM暂停(对用户而言程序失去响应,但是内部还是再做GC),而JVM调优带到的效果是:无非是使Full gc少执行,而小GC也少执行。

JVM内存模型分析(一个程序运行的例子)的更多相关文章

  1. JVM性能调优(1) —— JVM内存模型和类加载运行机制

    一.JVM内存模型 运行一个 Java 应用程序,必须要先安装 JDK 或者 JRE 包.因为 Java 应用在编译后会变成字节码,通过字节码运行在 JVM 中,而 JVM 是 JRE 的核心组成部分 ...

  2. 程序猿的日常——JVM内存模型与垃圾回收

    Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础--这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...

  3. JVM的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集

    (转自:http://my.oschina.net/u/436879/blog/85478) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认 ...

  4. JVM内存模型及垃圾收集策略解析(一)

    JVM内存模型是Java的核心技术之一,之前51CTO曾为大家介绍过JVM分代垃圾回收策略的基础概念,现在很多编程语言都引入了类似Java JVM的内存模型和垃圾收集器的机制,下面我们将主要针对Jav ...

  5. JVM内存模型与GC算法

    1.JVM内存模型 JVM内存模型如上图,需要声明一点,这是<Java虚拟机规范(Java SE 7版)>规定的内容,实际区域由各JVM自己实现,所以可能略有不同.以下对各区域进行简短说明 ...

  6. jvm内存模型-回收算法-和内存分配以及jdk、jre、jvm是什么关系(阿里,美团,京东面试题)

    1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个 ...

  7. jvm-垃圾回收gc简介+jvm内存模型简介

    gc是jvm自动执行的,自动清除jvm内存垃圾,无须人为干涉,虽然方便了程序员的开发,但同时增加了开发人员对内存的不可控性. 1.jvm内存模型简介 jvm是在计算机系统上又虚拟出来的一个伪计算机系统 ...

  8. Inside JVM 内存模型

    Inside JVM 内存模型 来源  原文:https://blog.csdn.net/silentbalanceyh/article/details/4661230 参考:IBM开发中心文档,&l ...

  9. [转]JVM内存模型

    最近排查一个线上java服务常驻内存异常高的问题,大概现象是:java堆Xmx配置了8G,但运行一段时间后常驻内存RES从5G逐渐增长到13G #补图#,导致机器开始swap从而服务整体变慢.由于Xm ...

随机推荐

  1. 【zabbix教程系列】四、用户自定义监控

    本篇介绍运用zabbix进行自定义监控,以系统用户登录数量为例. 一.zabbix自定义语法 UserParameter=<key>,<shell command> 二.age ...

  2. 如何在Linux中轻松删除源安装的软件包?

    第1步:安装Stow 在这个例子中,我们使用的是CentOS,因此我们需要扩展的EPEL库.您可以使用以下命令安装它们:yum install epel-release然后,下面这段命令:yum in ...

  3. Linux(Ubunt)使用日记------常用软件汇总(不定时更新)

    整理总结日常Ubuntu中使用的一些软件,事实证明使用Linux真的会让人的欲望变小有个能用的就不错啦,不要调三捡四 解压类 Unzip | unzip -O CP936 files Unrar ra ...

  4. [Cordova inAppBrowser 在App内打开浏览器]

    方案1: 使用Cordova插件 cordova-plugin-inappbrowser 1.  添加插件 cordova plugin add cordova-plugin-inappbrowser ...

  5. icns图标的制作

    1. 准备一张无损的png图片(1024x1024) 2. 新建一个文件夹 必须要以iconset为后缀 $ mkdir hgl_pngpic.iconset 3. 使用sips 命令剪切10个不一样 ...

  6. sqlserver建立远程查询

    开始远程查询前: ----open:Ad Hoc Distributed QueriesEXEC sp_configure 'show advanced options',1reconfigureex ...

  7. ansible-playbook用法

    一.playbook用法 1.playbook的执行文件为YAML语言编写,所以文件名为xxx.yml.YAML语法可以参考https://docs.ansible.com/ansible/lates ...

  8. 编写高质量的Python代码系列(八)之部署

    Python提供了一些工具,使我们可以把软件部署到不同的环境中.它也提供了一些模块,令开发者可以把程序编写的更加健壮.本章讲解如何使用Python调试.优化并测试程序,以提升其质量与性能. 第五十四条 ...

  9. Jupyter Notebook 的安装使用以及 tree 路径变更

    由于最近开始学习 Python,进而接触到一个十分强大的交互式编辑器 — Jupyter Notebook,用起来也非常顺手,于是记录一下相关的使用过程. 一.安装 Python: ①首先前往 pyt ...

  10. SpringBoot项目打成jar包后上传文件到服务器 目录与jar包同级问题

    看标题好像很简单的样子,但是针对使用jar包发布SpringBoot项目就不一样了.当你使用tomcat发布项目的时候,上传文件存放会变得非常简单,因为你可以随意操作项目路径下的资源.但是当你使用Sp ...