学习笔记 2021.10.20and21

2021.10.20and21

JVM

运行时数据区

虚拟区栈

各种变量类型的一个简单的比较。

image-20211026193222286

类变量即是在用static修饰的变量。

image-20211026193227629

更想知道的还是为什么静态方法中无法用this关键字。

image-20211026193232768

这个先记到这,后面用到再详细说

操作数栈(用数组来实现的栈结构)

image-20211026193239722

其他的一些需要注意的

image-20211026193244807

最后一条即是无法通过什么读数组下标之类的操作去进行数据访问,还是只有入栈和出栈。

image-20211026193249493

通过代码追踪演示有几点想说的:

  • 操作数栈是根据方法测试已经定义好的数组长度,即能够实现多个变量在不同时候使用时共享空间这么一个情况。
  • 入栈出栈后一般就紧跟着store的指令,即将数据存入局部变量表中的对应位置,也就是前面局部变量表有看到的信息。
  • 带有返回值的方法,会将返回值放在0位置,通过调用可以看出会第一时间load该数据放在栈底的位置用来使用。
栈顶缓存技术

由于虚拟机用的是精简指令的,所以自然在代码长时会造成指令过多。因此引入缓存技术。

image-20211026193255339

动态链接!?

image-20211026193304715

常量池:

image-20211026193311392

即转换为字节码文件后,会将所有使用到的信息化为符号存在常量池中去。常量池是存在于方法区中的结构。

符号引用就是#7之类的东西。

简单理解就是动态链接可以指向常量池中的具体方法名称。

这么做的意义即是有利于多次引用,而不至于每次使用都要创建一次。并且常量池的作用就是提供一些符号和常量便于指令的识别和引用。而不至于全部都放在内存中去。

这里看完了后面的方法区就相对好理解一点了。

早期绑定与晚期绑定

image-20211026193317674

即就是动态链接和静态链接差不多的意思。

image-20211026193322622

这时该方法就无法知道具体是哪个对象进行的方法调用,所以属于晚期绑定。

image-20211026193331340

虚函数即是晚期绑定。

image-20211026193337253

虚拟机中的几种方法调用指令:

image-20211026193343241

虚方法与非虚方法和四种方法的调用(再说)
方法重写的本质

image-20211026193351604

image-20211026193358738

创建的时候即是链接阶段的第一步,可以通过前面的记录看出来。正是因为虚方法指定不确定,所以说才会需要记录来节省时间。

image-20211026193406166

具体实现的方式就是将虚方法表中的对应方法按照重写的规定直接指向该调用的类,从而不用每次调用时都进行判断了。

方法返回地址的说明

image-20211026193412453

即有点像微嵌课程中中断的处理方法一样。

image-20211026193417747

概念上很好理解,最多就是字节码文件上的理解。

一些附加信息 略 用的很少
一些面试题

image-20211026193424133

最后一个,线程安全的定义其实是对于变量能否被不同的线程所调用,这里有个印象就可以了。

本地方法接口(其实是在运行时数据区外面的)

image-20211026193431593

这里意思即是用native关键字修饰的方法,都是没有方法体的,即是没法用java语言去实现的。

使用本地方法的原因:

image-20211026193438737

具体的应用包括操作系统和sun s java等等。

该接口即是用于在java程序中调用本地方法的接口。

本地方法栈

image-20211026193445524

与虚拟机栈类比着来记忆。

本地方法的执行和java方法执行的区别:

image-20211026193453662

首先说明由进程私有的含义即是一个进程对应着一个JVM实例即runtime对象。

堆的核心概述

image-20211026193500015

最后一条的意思是,在堆中还会分出一个区域提供每个线程独有的对空间用来解决共 用的问题,这一块空间也就叫做TLAB。

image-20211026193507101

第一条几乎的概念后面会具体解释。

第三条也就可以看出,由于方法的调用是非常频繁的,所以对于方法回收的线程和用户线程的协调是非常重要的问题了。

堆内存的细分

image-20211026193517249

逻辑上分为上面三部分,但其实实际拥有的就是前两部分。这里通过jvm visual看具体的堆的空间的分配就可以看出来。

image-20211026193524457

对于JDK7和8之间区域划分的区别,这里先做一个了解即可。

关于堆空间大小的一些概念和设置:

image-20211026193529858

一般设置的时候会把初始堆内存和最大对内存设置成相同的值,从而保证后面垃圾回收时不会出现其他的麻烦。

image-20211026193534127

这些都是后面用到的话再去具体了解。

注意这里会出现计算跟实际结果不同的情况,其实就是伊甸区和s区的设置问题,后面会说。

年轻代和老年代的解释

image-20211026193540393

区分的意义就在于对于那些存在周期很长的对象,就不要频繁的去进行垃圾回收浪费时间了。

新生代与老年代所占空间的比例也可以进行调整,具体根据实际调整需求去改即可。包括很多调参数的配置也都是这样的。

image-20211026193546865

第三条例外即是对象大到伊甸园区放不下的时候才会考虑创建在其他地方。

具体分配空间过程

概述:

image-20211026193554255

  • minorGC也叫YGC。

  • 第三步的意思就是对于一开始放进伊甸区的对象,在第一次YGC判断不是垃圾过后,放到s0区。

  • 当第二次触发YGC的时候,不管伊甸区还是s0区中不是垃圾的对象都放到S1区去。

  • 后面的每次过程都是重复的,都是把还没有变成垃圾的对象放到空的s区中去。

  • 每次换位置的过程都会把age的一个变量加一。

  • 空的区也叫to区,有对象的区就是from区。

  • 当age的次数达到一定的次数后,就会直接放到老年区中去。

  • 也要注意到s区满的时候不会触发YGC,但是他会在伊甸区满的时候一起触发。

  • 也有对象可能一生成就放到老年区去了。

    image-20211021112840562

    当然,老年区触发GC的可能性就相对小点了。

image-20211026193600966

一些特殊的情况:

image-20211026193608719

其中FGC即是老年区的垃圾回收。

并且注意到报OOM时一般是在老年区?

常用调优工具!!

后面用到时再去下载和了解。都是可以用来去看内存空间的。

posted @ 2021-10-26 19:38  damndamit  阅读(57)  评论(0)    收藏  举报