首页 > 其他分享 >9.20学习

9.20学习

时间:2024-09-21 20:23:42浏览次数:3  
标签:初始化 9.20 对象 虚拟机 学习 线程 引用 方法

设计模式与原则

1.单例模式

​某个类只能生成一个实例,该实例全局访问,例如Spring容器里一级缓存里的单例池。

优点:

唯一访问:如生成唯一序列化的场景、或者spring默认的bean类型。

提高性能:频繁实例化创建销毁或者耗时耗资源的场景,如连接池、线程池。

缺点:

不适合有状态且需变更的

实现方式:

饿汉式:线程安全速度快

懒汉式:双重检测锁,第一次减少锁的开销、第二次防止重复、volatile防止重排序导致例化未完成

静态内部类:线程安全利用率高

枚举:effictiveJAVA推荐,反射也无法破坏

2.工厂模式

​定义一个用于创建产品的接口,由子类决定生产何种产品。

优点:解耦:提供参数即可获取产品,通过配置文件可以不修改代码增加具体产品。

缺点:每增加一个产品就得新增一个产品类

3.抽象工厂模式

提供一个接口,用于创建相关或者依赖对象的家族,并由此进行约束。

优点:可以在类的内部对产品族进行约束

缺点:假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。

 

4.构造方法

构造方法可以被重载,只有当类中没有显性声明任何构造方法时,才会有默认构造方法。

构造方法没有返回值,构造方法的作用是创建新对象。

5.初始化块

静态初始化块的优先级最高,会最先执行,在非静态初始化块之前执行。

静态初始化块会在类第一次被加载时最先执行,因此在 main 方法之前。

6.this

关键字 this 代表当前对象的引用。当前对象指的是调用类中的属性或方法的对象

关键字 this 不可以在静态方法中使用。静态方法不依赖于类的具体对象的引用

7.重写和重载的区别

重载指在同一个类中定义多个方法,这些方法名称相同,签名不同。

重写指在子类中的方法的名称和签名都和父类相同,使用override注解

8.object类方法

toString 默认是个指针,一般需要重写

equals 比较对象是否相同,默认和==功能一致

hashCode 散列码,equals则hashCode相同,所以重写equals必须重写hashCode

finalize 用于垃圾回收之前做的遗嘱,默认空,子类需重写

clone 深拷贝,类需实现cloneable的接口

getClass 反射获取对象元数据,包括类名、方法、

notify、wait 用于线程通知和唤醒

9.基本数据类型和包装类

5349d75493974cdda628f3cab358dadc.jpg

198fdef94a9b47919e55cbe773e55656.jpg 

 

10.jvm运行时数据区域​

堆、方法区(元空间)、虚拟机栈、本地方法栈、程序计数器

    7bf0c792ac3d46bd9feca21a401dd2bd.jpg

 

 

Heap(堆):

对象的实例以及数组的内存都是要在堆上进行分配的,堆是线程共享的一块区域,用来存放对象实例,也是垃圾回收(GC)的主要区域;开启逃逸分析后,某些未逃逸的对象可以通过标量替换的方式在栈中分配堆细分:新生代、老年代,对于新生代又分为:Eden区和Surviver1和Surviver2区;

 

方法区:

对于JVM的方法区也可以称之为永久区,它储存的是已经被java虚拟机加载的类信息、常量、静态变量;Jdk1.8以后取消了方法区这个概念,称之为元空间(MetaSpace);

 

当应用中的 Java 类过多时,比如 Spring 等一些使用动态代理的框架生成了很多类,如果占用空间超出了我们的设定值,就会发生元空间溢出

 

虚拟机栈:

虚拟机栈是线程私有的,他的生命周期和线程的生命周期是一致的。里面装的是一个一个的栈帧,每一个方法在执行的时候都会创建一个栈帧,栈帧中用来存放(局部变量表、操作数栈 、动态链接 、返回地址);在Java虚拟机规范中,对此区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将会抛出StackOverflowError异常;如果虚拟机栈动态扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

 

局部变量表:局部变量表是一组变量值存储空间,用来存放方法参数、方法内部定义的局部变量。底层是变量槽(variable slot)

 

操作数栈:是用来记录一个方法在执行的过程中,字节码指令向操作数栈中进行入栈和出栈的过程。大小在编译的时候已经确定了,当一个方法刚开始执行的时候,操作数栈中是空发的,在方法执行的过程中会有各种字节码指令往操作数栈中入栈和出栈。

 

动态链接:因为字节码文件中有很多符号的引用,这些符号引用一部分会在类加载的解析阶段或第一次使用的时候转化成直接引用,这种称为静态解析;另一部分会在运行期间转化为直接引用,称为动态链接。

 

**返回地址(returnAddress):**类型(指向了一条字节码指令的地址)

 

JIT即时编译器(Just In Time Compiler),简称 JIT 编译器:

 

为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化,比如锁粗化等

 

本地方法栈:

 

​ 本地方法栈和虚拟机栈类似,不同的是虚拟机栈服务的是Java方法,而本地方法栈服务的是Native方法。在HotSpot虚拟机实现中是把本地方法栈和虚拟机栈合二为一的,同理它也会抛出StackOverflowError和OOM异常。

 

PC程序计数器:

 

​ PC,指的是存放下一条指令的位置的一个指针。它是一块较小的内存空间,且是线程私有的。由于线程的切换,CPU在执行的过程中,需要记住原线程的下一条指令的位置,所以每一个线程都需要有自己的PC。

 

11.堆内存分配策略

    2c245c3cd80e456db01084152e5bc02c.jpg

 

 

对象优先分配在Eden区,如果Eden区没有足够的空间进行分配时,虚拟机执行一次MinorGC。而那些无需回收的存活对象,将会进到 Survivor 的 From 区(From 区内存不足时,直接进入 Old 区)。

 

大对象直接进入老年代(需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法收集内存)。

 

长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄(Age Count)计数器,如果对象经过了1次Minor GC那么对象会进入Survivor区,之后每经过一次Minor GC那么对象的年龄加1,直到达到阀值(默认15次),对象进入老年区。

 

(动态对象年龄判定:程序从年龄最小的对象开始累加,如果累加的对象大小,大于幸存区的一半,则将当前的对象 age 作为新的阈值,年龄大于此阈值的对象则直接进入老年代)

 

每次进行Minor GC或者大对象直接进入老年区时,JVM会计算所需空间大小如小于老年区的剩余值大小,则进行一次Full GC。

 

12.创建一个对象的步骤

步骤:类加载检查、分配内存、初始化零值、设置对象头、执行init方法

 

①类加载检查:

虚拟机遇到 new 指令时,⾸先去检查是否能在常量池中定位到这个类的符号引⽤,并且检查这个符号引⽤代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执⾏相应的类加载过程。

 

②分配内存:

在类加载检查通过后,接下来虚拟机将为新⽣对象分配内存,分配⽅式有 “指针碰撞” 和 “空闲列表” 两种,选择那种分配⽅式由 Java 堆是否规整决定,⽽Java堆是否规整⼜由所采⽤的垃圾收集器是否带有压缩整理功能决定。

 

③初始化零值:

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值,这⼀步操作保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使⽤,程序能访问到这些字段的数据类型所对应的零值。

 

④设置对象头:

初始化零值完成之后,虚拟机要对对象进⾏必要的设置,例如这个对象是那个类的实例、如何才能找到类的元数据信息、对象的哈希吗、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运⾏状态的不同,如是否启⽤偏向锁等,对象头会有不同的设置⽅式。

 

⑤执⾏ init ⽅法:

从虚拟机的视⻆来看,⼀个新的对象已经产⽣了,但从Java 程序的视⻆来看, ⽅法还没有执⾏,所有的字段都还为零。所以⼀般来说(除循环依赖),执⾏ new 指令之后会接着执⾏ ⽅法,这样⼀个真正可⽤的对象才算产⽣出来。

 

13.对象引用

普通的对象引用关系就是强引用。

软引用用于维护一些可有可无的对象。只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。

弱引用对象相比软引用来说,要更加无用一些,它拥有更短的生命周期,当 JVM 进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。

虚引用是一种形同虚设的引用,在现实场景中用的不是很多,它主要用来跟踪对象被垃圾回收的活动。

 

happy everyday

标签:初始化,9.20,对象,虚拟机,学习,线程,引用,方法
From: https://blog.csdn.net/2401_87363162/article/details/142392928

相关文章

  • 9.21学习
    1.JVM类加载过程过程:加载、验证、准备、解析、初始化 加载阶段:1.通过一个类的全限定名来获取定义此类的二进制字节流。2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。3.在Java堆中生成一个代表这个类的java.lang.class对象,作为方法区这些数据的访......
  • D13【python接口自动化学习】-python基础之内置数据类型
    day13集合学习日期:20240920学习目标:内置数据类型--22常见常新:集合的常见操作学习笔记:集合与set对象创建set对象set对象的常用操作#使用set对象对元组去重color=('r','g','b','g','b','b')#创建元组new_color=set(color)#转换set对象去重print(new_color)#......
  • 学习 vxworks引发的追问
    VxWorks是WindRiver开发的一款商用嵌入式实时操作系统(RTOS),广泛应用于航空航天、国防、工业控制、汽车、通信等领域。学习VxWorks涉及操作系统的基本概念、嵌入式系统开发、实时系统编程等多个领域,因此需要有一个循序渐进的学习方案。以下是一个详细的学习方案及流程:......
  • D14【python接口自动化学习】-python基础之内置数据类型
    day14字典的定义学习日期:20240921学习目标:内置数据类型--23字典:如何处理映射类型的数据?学习笔记:映射与字典字典的定义字典的删除总结字典用于存储键值对,键值对之间有关联字典键要求可哈希,一般采用字符串,元组做字典的键值可以使用dic()函数、推导式和花括号{}三......
  • java学习9.21
    今天回炉mybatis的用法,由于之前只是跟着教程走能成功配置数据库,但是一旦出现细小的区别就会产生自己改不了的bug,因此熟悉mybaits和其他技术的内容。知道问题出在哪里,以及怎么改。mybatis配置1.导入操作(1)官网下载jar包并导入(2)maven直接导入依赖2.导入完之后创建mybatis-co......
  • 学习STM32的震动开关
    学习STM32的震动开关在本文中,我将详细介绍如何使用STM32微控制器来实现一个震动开关。震动开关是一种能够检测物体是否发生震动的传感器,通常用于安防系统、智能家居等领域。我们将使用STM32的GPIO模块和外部中断功能来实现震动开关的功能。前期准备在开始之前,我们需要准备以......
  • 学习STM32的OLED显示屏控制
    引言:OLED(OrganicLightEmittingDiode)屏幕是一种新型的显示技术,它使用有机材料作为发光器件,具有高对比度、快速响应、广视角和低功耗等特点。STM32是一家全球领先的微控制器制造商,其产品家族中包括了多种型号的ARMCortex-M系列的微控制器。在本文中,我们将介绍如何使用STM32......
  • 学习STM32的火焰传感器
    火焰传感器是一种用于检测火焰存在的电子设备。它可以广泛应用于火灾检测、火焰监控和安全预警等领域。本文将详细介绍如何使用STM32开发板和火焰传感器来实现火焰检测功能,并给出相应的代码案例。一、硬件准备首先,需要准备以下硬件设备:STM32开发板(如STM32F103C8T6)火焰传感器......
  • CL260 学习笔记(三)
    Ceph存储池如果PG太多,对象太少,会造成大量的空间浪费;如果PG太少,对象太多,寻找对象的时间过长,影响性能。cephosdpoolcreate--helpusage那一行显示的是存储池内所有pg的容量之和。这里提出一个问题:pg_num是32个,那么osd上有多少个pg?这是一个replicated(副本)池,size是3,表示是3......
  • Vue学习笔记6:分别使用纯JavaScript和Vue的v-if 指令来有条件地渲染网页元素
    0缘起有时我们的网页需要根据需要用户的选择展示不同的页面元素。例如:<p>你喜欢哪种水果?</p><p> <label> <inputtype="radio"value="苹果"name="fruit"/> 苹果 </label></p><p> <label> <inputtype="ra......