JVM内存模型分析(一个程序运行的例子)
(.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内存模型分析(一个程序运行的例子)的更多相关文章
- JVM性能调优(1) —— JVM内存模型和类加载运行机制
一.JVM内存模型 运行一个 Java 应用程序,必须要先安装 JDK 或者 JRE 包.因为 Java 应用在编译后会变成字节码,通过字节码运行在 JVM 中,而 JVM 是 JRE 的核心组成部分 ...
- 程序猿的日常——JVM内存模型与垃圾回收
Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础--这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...
- JVM的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集
(转自:http://my.oschina.net/u/436879/blog/85478) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认 ...
- JVM内存模型及垃圾收集策略解析(一)
JVM内存模型是Java的核心技术之一,之前51CTO曾为大家介绍过JVM分代垃圾回收策略的基础概念,现在很多编程语言都引入了类似Java JVM的内存模型和垃圾收集器的机制,下面我们将主要针对Jav ...
- JVM内存模型与GC算法
1.JVM内存模型 JVM内存模型如上图,需要声明一点,这是<Java虚拟机规范(Java SE 7版)>规定的内容,实际区域由各JVM自己实现,所以可能略有不同.以下对各区域进行简短说明 ...
- jvm内存模型-回收算法-和内存分配以及jdk、jre、jvm是什么关系(阿里,美团,京东面试题)
1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个 ...
- jvm-垃圾回收gc简介+jvm内存模型简介
gc是jvm自动执行的,自动清除jvm内存垃圾,无须人为干涉,虽然方便了程序员的开发,但同时增加了开发人员对内存的不可控性. 1.jvm内存模型简介 jvm是在计算机系统上又虚拟出来的一个伪计算机系统 ...
- Inside JVM 内存模型
Inside JVM 内存模型 来源 原文:https://blog.csdn.net/silentbalanceyh/article/details/4661230 参考:IBM开发中心文档,&l ...
- [转]JVM内存模型
最近排查一个线上java服务常驻内存异常高的问题,大概现象是:java堆Xmx配置了8G,但运行一段时间后常驻内存RES从5G逐渐增长到13G #补图#,导致机器开始swap从而服务整体变慢.由于Xm ...
随机推荐
- mysql创建函数之省市区数据查询
DROP FUNCTION IF EXISTS queryChildrenAreaInfo;CREATE FUNCTION queryChildrenAreaInfo(areaId varchar(2 ...
- Tomcat配置实例
转自:https://www.cnblogs.com/kismetv/p/7228274.html 目录 一.一个server.xml配置实例 二.server.xml文档的元素分类和整体结构 1.整 ...
- Linux centos ansible
创建m01.backup.nfs.web01.web02 m01(172.16.1.61).backup(172.16.1.41).nfs(172.16.1.31).web01(172.16.1.7) ...
- Python openpyxl : Excel 文档简单操作
安装方法 使用 pip 或通过专门python IDE(如pyCharm)进行安装 其中pip安装方法,命令行输入: pip install openpyxl 基本使用 第一步先是要导入 openp ...
- Spring Mybatis多数据源配置范例
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- this.setData , that.setData , this.data.val三者之间的区别和作用
1.this.setData({ }) <view bindtouchmove="tap_drag" bindtouchend="tap_end" bin ...
- js中字符串可以调用的方法
var s = "hello,world" //定义一个字符串 s.length() // => 11 s.charAt(0) ...
- git学习02 - log查看&版本回退
1.查看更新记录 git log / git log --pretty=oneline D:\learn\git_test>git log commit a915e7b12076673d778 ...
- POJ2975 Nim 【博弈论】
DescriptionNim is a 2-player game featuring several piles of stones. Players alternate turns, and on ...
- 关于gcd的四道题
T1:bzoj2705 题目描述: 给定一个n求\(\sum\limits_{i=1}^ngcd(i,n)\) 因为n太大,所以O(n)的做法肯定不行,然后就去想根号的方法. \[\sum\limit ...