快速了解JVM基础知识

1.JVM内存模型

JVM:为应用程序屏蔽底层操作系统的细节,为web提供必要的运行支持能力。在C++中,内存管理需要程序员手动释放,可能会造成悬挂引用(对象的引用指向错误的地址),内存泄露(对象占用内存没有释放,又没有引用指向这个对象),Java的jvm提供了gc的机制,让开发人员更注重业务功能的实现,自动管理内存。
JCM内存模型

java堆:内存空间很大。对象实例和数组在堆上分配。也叫做GC堆。

方法区:存储被虚拟机加载的类信息,常量,静态变量。垃圾回收时是类型的卸载和常量池的回收。

java栈:方法执行时会创建一个栈帧(包括局部变量表,操作数栈,动态链接,方法出口),
		每一个方法从调用直至完成的过程,对应一个栈帧在虚拟机栈中的入栈到出栈。
		局部变量表存放编译期可知的各种基本数据类型,对象引用,returnAddress。局部变量表的内存空间在
		编译器完成分配,运行期间不会改变局部变量表的大小。
		如果线程请求的栈深度大于虚拟机栈允许深度。StackOverFlowError,如果虚拟机栈动态扩展,扩展
		时无法申请到足够的内存,抛出OutOfMemoryError异常。
		
本地方法栈:java虚拟机栈为java方法(字节码)服务,本地方法栈为native方法服务。native方法是访问操作系统的原生代码。

程序计数器:较小的内存空间,记录当前执行的的字节码指令的地址,通过改变计数器的值取下一条需要执行的字节码指令。

 堆和方法区是GC对象
 java栈,程序计数器,本地方法栈是线程私有的。

JNI(Java Native Interface):java本地接口,调用底层原声代码的方法。native是标识。

1.java编译和运行的过程

1.找到.java文件,先编译.java文件所依赖的类,生成.class文件。
2.,class文件分为常量池和方法字节码。
常量池:记录代码出现的token(类名,成员变量名,方法名,变量引用)
方法字节码:存放各方法字节码。
3.类加载。
当运行java程序时,启动jvm进程,jvm进程通过双亲委派机制找到类加载器(启动类加载器,扩展类加载器,应用程序类加载器),从子类委派到启动类加载器,启动类加载器找不到相关的.class文件,交由子类完成,这里的jvm进程是通过应用程序类加载器从classpath路径下加载.class的二进制文件,将类的类型信息加载到运行时数据区的方法区中。(类的加载)
4.主函数入口开始执行
5.创建类的实例,由于方法区中只有public类的类信息,所以如果是创建其他普通类的实例,jvm需要再去通过类加载器加载classpath下的相应的类的.class文件,在方法区中找到类信息后,在堆中为实例对象分配内存,这个实例有指向方法区的普通类的类型信息的引用,(其中包含有方法表,java动态绑定的底层实现)。
(绑定:将方法与类/对象关联)
(动态绑定:多态实现的重要因素,通过方法表实现动态绑定,程序运行过程中,根据实例对象确定调用哪个方法)
(静态绑定:程序运行前就知道方法属于哪一个类,编译时链接到类中,定位到这个方法)
final,private,static修饰的方法是静态绑定的。
6.栈中存储指向实例对象的引用,当调用实例方法时,在栈中根据引用找到堆中的实例对象,实例对象通过引用定位到方法区中类信息的方法表,获得该方法的字节码地址。
7.运行

2.运行时数据区中的堆区的结构

新生代:eden,s0(from),s1(to)(eden:s0:s1=8:1:1)
老年代:major gc,新生代经历15次垃圾回收还存活的对象进入老年代。
永久代:对应方法区(java8之前是永久代,之后是元空间,实际上是非对内存,不存在,逻辑上存在)
OOM异常:OutOfMemeryError.java heap space
原因:
1.jvm的堆内存设置不够,通过参数-Xmx,Xmx调整
2.创建大量对象,长时间没有gc。
3.存在无法使用的内存区域,比如对象移出队列,简单的++,无法访问小于topIndex的对象。

3.垃圾回收器的实现方式

1.并发运行:与程序同时运行,(复杂,内存状态不断变化,不容易判断)
2.暂停执行:简单,但对程序有影响,可能会暂停一下,影响体验。
对象处于活动状态是有引用指向的时候。

强引用:gc时无论是否异常,都不回收
软引用:gc时内存不够就回收
弱引用:gc时就会搜
虚引用:没有指向对象,回收对象时做一个跟踪活动,加入到引用队列中,

GC算法判断指向对象的引用是否存在:
1.引用计数器:有新应用指向+1,对象的值设为null,-1
缺陷:不能解决循环引用孤岛,两个或者三个对象互相存在引用,引用计数器是1,gc不回收
2.跟踪对象引用(可达性算法分析):
从根节点开始,递归检查对象所引用的其他对象,直到找到不指向其他对象的引用(也是对象)为止,
将这些找到的对象标记为存活的,构成根集合,存活对象为可达对象,路径为可达路径,边为引用。

JNI:提供一个方式让java层序通过虚拟机与原生代码进行交互。
1.提升性能,耗时代码用c c++实现
2.与c c++开发的程序交互

java3之后JVM的底层用hotSpot实现
java执行字节码时用即时编译(JIT,Just in time),jvm在运行过程中把字节代码的指令转换为操作系统平台上的原生指令,
JVM只理解class格式,JIT会降低执行效率。

hotSpot采用自适应优化技术解决
程序运行过程中,程序局部性的特点,小部分代码占据较多的时间成为热点,80-20原则,所以对20%代码优化。

新生代的gc算法是:复制算法。(将存活对象复制到另一个内存空间)
对老年代和永久代:
标记、清除、压缩算法。
标记:扫描整个内存区域,标记存活的对象。
清除:清理内存区域。
压缩:压缩整个内存区域,存活对象移动到内存起始位置,保证连续性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值