学习JVM笔记

学习JVM笔记

JDK Java开发工具,包含JRE 和JVM ;
JRE Java运行环境,包含JVM ;
JVM 处理Java编译好的字节码文件,执行代码,可处理任意平台,如windows、linux等等。
思考:JVM只能运行Java的.class(字节码)文件吗,

答案是否定的,其它语言只要也符合字节码文件的规则,JVM都是可以运行。

字节码文件的基本执行流程

class文件–>类加载器–>JVM内存(运行时数据区)–>执行引擎–>操作系统
字节码执行流程

JVM的内存管理
自动化管理,内存分配自动,垃圾回收自动。

举个例子:把class文件的执行比作我们吃东西的一个过程,那class文件就是食物,喉咙作为我们的类加载器来接收食物,我们的胃就是JVM内存,消化吸收,将营养分配到五脏六腑,到最后的排泄,就是一个垃圾自动回收。

运行时数据区

JVM在运行过程中会把它所管理的内存划分成为若干不同的数据区域!

线程私有:虚拟机栈、本地方法栈、程序计数器
程序共享:堆、方法区

JVM数据区

栈(Stack):数据结构

入口和出口只有一个,先进后出(FILO)。
模型可以想象成一个杯子,而先放进去的,只能后被拿出来,后放进去的,可以先拿出来。(不要杠精附体,比如沙子等等)
栈模型

线程私有

1、程序计数器

指向当前线程正在执行的字节码指令的地址(行号),会记录其他线程的字节码指令的地址(行号),

思考:为什么需要程序计数器

1、因为Java是多线程的语言,意味着我们会线程切换,如果没有程序计数器,当我在线程来回切换的过程中,我不知道我刚刚执行到哪里了;
2、确保多线程情况下的程序能正常执行,不会被来回切换而错乱。

2.运行时数据区-虚拟机栈

存储当前线程运行方法所需的数据、指令、返回地址等

2.1栈帧

类中每一个方法对应一个栈帧
栈帧还可以划分为:
局部变量表:第0号位置,指向的是this,也就是类对象的本身,其它位置,指向定义的参数,其他位置,依次是定义的变量;
操作数栈:定义的变量在需要发生变化,在此栈中操作;
动态连接:执行的时候才知道指向哪里,它指向的是我们的引用链接;
返回地址:return语句的执行。
虚拟机栈中的栈帧
javap -v 类名.class 可以将字节码文件反编译。

3.本地方法栈

为虚拟机执行Native方法服务。

线程共享(数据)/JMM:JVM的内存模型

堆:存放对象,成员变量等,在JMM中表现为新生代和老年代;

新生代还可以分为:
Eden空间,
From空间,
To空间,
新生代一般占据堆内存的三分之一内存;
老年代:一般占据堆内存的三分之二内存;
元空间:在jdk1.8及其以上叫元空间,在jdk及其以下,叫老年代。

方法区:存放静态变量,final常量等,在JMM中表现为元空间。
对象分配原则:

1、对象优先在Eden分配,
2、大对象直接进入老年代,
3、长期存活的对象将进入老年代,
4、动态对象年龄判定,
5、空间分配担保。
在新生代中,Eden:From:To 是8:1:1的原则进行内存分配;
假设堆内存分配到300M内存,那么新生代就会得到100M内存,老年代得到200M内存,那么自然的,Eden、From、To就分别为80M,10M,10M的空间,当我们在Eden空间中存放了79.5M的对象,此时再来1M的对象,就会触发GC垃圾回收,没有用的就会被回收掉,有用的会进入From空间,并对此对象进行一个年龄计算,每回收一次,年龄加1,默认年龄为15之后,进入老年代。
如果From空间或者To空间中存放对象的内存超过本身内存的百分之五十,就会有一个动态年龄的判断,触发垃圾回收算法(MinorGC),提前晋级老年代。
在老年代中,如果我们存放的对象快要将内存占满,此时新生代中有对象要进入老年代,但是老年代的空间无法满足存储这个对象,就会触发垃圾回收算法(FullGC),对之前的对象进行回收,来确保我们新生代对象能放入老年代。
JMM

JMM–对象的回收——判断对象的存活

假如在程序中,定义了一个常量,此常量对象在老年代中,当常量在程序中被引用,那么就认为此常量是可达的,反之,则为不可达。
可达性分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值