一.JVM基础
1.jvm是什么?
屏蔽了底层硬件,指令层面的细节。负责连接字节码和机器之间。
2.为什么要学习JVM?
方便了内存管理,不用程序员管理内存管理。
但是,如果内存管理出问题,比如内存溢出啥的,就需要程序员去解决,
就必须要学习JVM。
二、运行时数据区
1.java运行的时候,各个数据区市怎么运行的。
方法区:存储数据的类信息,meta信息,常量,static静态变量,叫做永久带。
堆:存放对象,分为新生代和老年代。
程序计数器:指向当前线程正在执行的字节码指令的地址(行号)
虚拟机栈:存储当前线程运行方法所需要的数据,指令和返回地址。也叫做存储当前的栈帧,一个方法就是一个栈帧。
一个栈帧中存储了
局部变量表:存储方法中的局部变量的表,这个表是定长的一张表。每个变量占一个32位长的基本变量。
操作数栈:将局部变量压入操作数栈,进行运算后出栈,再次写入局部变量表
动态链接:比如@Autowired注解的实现方式,运行时多态。
出口:方法执行完成之后去哪里
异常执行完:
正常执行完:
本地方法栈:类似于虚拟机栈,存放本地方法需要的数据,指令和返回地址。
新生代中有eden,s0和s1区。比例为8:1:1。新生代中用的垃圾回收算法时,用复制回收算法。
Minor gc /yong gc:如果eden区中只有8兆,然后正好有个8兆的对象,这个新建的8兆的对象
就会被放到eden区,,,恰好此时又要来一个一兆的对象,那么如果这个新的对象要回收,
这个时候就会触发young gc去回收。如果不可以被回收,首先会到s0区,s0区放不下,
然后就会触发一个担保机制,就会存到老年代。这个时候1兆的那个对象就可以存到eden区了。
1.8以后,没有永久代了,替而代之的是meta space,meta space是为了解决永久代益处问题的
,有了这个,就会运用了类似arraylist的自动扩容的机制,来扩容。支持可变大小。
问题:
动态链接为什么要放到栈帧里边?
什么样的对象能被回收,什么样的对象不能被回收?