JVM内存模型笔记

JVM是运行在操作系统之上的,和硬件没有直接关系

类加载器,运行时数据区域,

运行时数据区域:堆,虚拟机栈,方法区,程序计数器,本地方法栈

:存储对象

虚拟机栈(FILO:先进后出)(线程独立):例如执行main方法,虚拟机栈会划出一块栈帧空间,存储main方法,先压入栈,然后main方法执行中有exe()方法,再开辟一块栈帧空间存储exe()方法信息,再压入栈。执行完exe()方法,则把此方法抛出。因为栈是在线程创建时创建,它的生命周期即是线程的生命周期,当线程结束,内存释放,所以不存在垃圾回收问题

存储内容:

  本地变量:输入参数 和 输出参数 以及方法内的变量

  栈操作:记录入栈,出栈的操作

  栈帧数据:包括类文件,方法等

方法区(1.8之前叫持久代或永久带,1.8之后叫元空间):存储静态变量,常量,类元信息,运行时常量池等

程序计数器:当前线程执行的行数

本地方法栈:存放native的方法,此类接口由java调用底层的c实现

===========

1.8之后方法区使用的内存是直接内存,即非虚拟机内存。若服务器总内存16G内存,虚拟机分配了1G内存,直接内存是从另外15G里使用

栈管运行,堆管存储

线程共享区域:方法区,堆

线程私有区域:虚拟机栈,程序计数器,本地方法栈

查看更可读的字节码文件:找到XXX.class文件,右键,找到Open in terminal,在弹出的输入框中输入:javap  -c  XXXX.class 

若保存成文件:javap  -c  XXXX.class  > XXXX.txt

动态链接,可查看格式:javap  -v  XXXX.class  > XXXX.txt

如上即是虚拟机指令

程序计数器会从0开始,往下指向

冒号后面的即是虚拟机指令,可从官网的虚拟机指令中查找对应的意思

栈帧:

局部变量表:存放局部变量

操作数栈(FILO):例如 a= 30; Int类型的30先放到操作数栈,然后a变量在局部变量表,然后把30弹出操作数栈,将30赋值给a

动态链接:线程中很多方法对应的指令码,指令码是程序运行中动态生成的。因此可以在一个方法中的方法名称调用到另一个方法

方法出口:存放上一个方法调回信息等

堆:

年轻代(Eden,Survivor(From,To))和老年代,一般默认年轻代占1/3,老年代占2/3内存。年轻代州Eden占8/10,From占1/10,To占1/10.

对象产生,先存入Eden中,若Eden满了,会触发 执行引擎 执行minor gc(新生代的gc),第一次垃圾回收,会回收Eden中的对象,若未被回收,则数据存入From中(若数据过大,超过From的50%,则直接存入老年代),并且分代年龄+1。垃圾回收第二次,回收内存Eden和From,不需要被回收的对象存入To内存中,并且分代年龄再+1,From内存清空。第三次垃圾回收,回收内存Eden 和 To,不需要被回收的对象存入From内存中,分代年龄再+1。如此循环,分代年龄15次还存活的对象存入老年代。

若老年代满了,则会执行full gc/magor gc,会STW(stop the word)

JNI:java native interface

类元信息

对象头:Mark Word(标记字段),Klass Pointer(类型指针),数组长度

标记字段: 自身运行时的数据:  哈希值,GC分代年龄,锁状态标记,线程持有锁,偏向线程Id,偏向时间戳

类型指针:类的元数据的指针

数组长度:只有数组中对象才有

=====

GC Root 根节点:类加载器,Tread,虚拟机栈的本地变量表,static成员,常量引用,本地方法栈的变量等

java visualVM 软件可以查看VM运行窗口,包括eden,survivor(from,to),老年代

JVM调优目的:减少full gc的次数,减少一次full gc的时间

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值