关于线程、泛型、类加载的知识点

1、线程的生命周期
java线程的生命周期可以划分为以下几个阶段:

新建(New):当线程对象对创建后,它只是进入了新建状态,此时它已经有了内存空间和其他资源,但线程还没开始执行。

就绪(Runnable):当调用线程对象的start()方法,线程即进入就绪状态。处于这个状态的线程位于可运行线程池中,等待获取CPU的使用权。

运行(Running):当CPU开始调度处于就绪状态的线程,使得线程进入运行状态。此时,它才真正开始执行run()方法里面的代码。

阻塞(Blocked):一个正在运行的线程如果调用了某些方法,如等待输入/输出完成,或者等待获取某个同步锁,则线程会进入阻塞状态,并且释放CPU使用权。

终止(Terminated):线程会在以下几种情况下进入终止状态:
正常运行的线程完成了run()方法里面的代码。
线程被提前强制性地中止,如通过调用stop()方法或destroy()方法。
线程执行过程中出现了异常导致意外终止。

2、什么是死锁?如何解决死锁?
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无限等待。

防止死锁的方法:
确定锁的顺序,并且整个应用中都按照这个顺序来获取锁。
超时放弃

可以使用wait和notify(notifyAll)方法


3、类加载的过程
(1)、加载:查找并加载类的二进制数据。

(2)链接:

验证:确保被加载的类的正确性。

准备:为类分配内存,并初始化静态变量。
在方法区中,为常量属性分配空间并初始化:为静态属性分配空间,并赋予了缺省值(没有初始化)。

解析:将类中的符号引用转换为直接引用。

(3)初始化:为类的静态变量赋予正确的初始值。
                     给静态属性初始化(属性的赋值语句,静态块)

4、Java有哪些类加载器?
Java的类加载器主要分为三类:启动类加载器、扩展类加载器和应用程序类加载器。


5、类加载机制
双亲委派机制:
双亲委派机制(Parent-Delegate Model)是Java类加载器中采用的一种类加载策略。该机制的核心思想是:如果一个类加载器收到了类加载请求,默认先将该请求委托给其父类加载器处理。只有当父级加载器无法加载该类时,才会尝试自行加载。

6、垃圾回收
Java的垃圾收集器是Java虚拟机(JVM)的一个组成部分,它可以自动管理应用程序的内存。垃圾收集器会回收程序不再使用的对象所占用的内存,以防止内存泄漏。

对象存活判断:
标记计数法
可达性分析算法

Java的垃圾收集器有多种算法,例如:
标记-清除
标记-整理
复制算法
分代收集

7、jvm内存分配
JVM内存分配主要指的是JVM运行时数据区的划分,包括:

程序计数器(Program Counter Register)
虚拟机栈(VM Stack)
本地方法栈(Native Method Stack)
堆(Heap)
方法区(Method Area)


详解:
JVM方法区是用于保存已经被虚拟机加载的类元信息(包括类的版本、字段、方法、接口和父类等信息)、运行时常量信息(static、final定义的常量)、字符串常量信息(String a="dfc")。

栈帧里存储着方法的局部变量表(保存着变量的数据)、操作数栈(进行运算时存放数据的空间)、动态连接(指向常量池的引用)和方法返回地址(当前方法返回后的数据存放的地方)信息。

由于java需要与一些底层系统如操作系统或某些硬件交换信息时的情况,这个时候就需要通过调用native本地方法来实现,本地方法栈和虚拟机栈功能差不多,区别在于本地方法栈是虚拟机调用native方法时使用的。

程序计数器是一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器,程序计数器记录着某个线程当前执行指令的位置,此区域属于线程隔离区。

堆内存主要是用来存放创建的对象数据,此区域属于线程共享区


8、jvm调优
JVM性能调优的主要目标是提高Java应用程序的响应速度、吞吐量和稳定性,同时减少资源消耗(如CPU、内存和磁盘I/O)。调优工作通常包括以下几个方面:

内存管理:包括堆内存、栈内存和非堆内存(元空间或永久代)的调整。
垃圾回收(GC):选择合适的垃圾回收器并调整其参数,以减少GC停顿时间和提升GC效率。
JIT编译优化:通过调整JIT编译器的行为来优化字节码到机器码的转换过程。
线程管理:优化线程池的使用,减少线程上下文切换,提高并发性能。
代码优化:从应用程序层面优化代码,减少不必要的资源使用和性能瓶颈。


其中,堆内存调优
堆内存是JVM中用于存储对象实例和数组的内存区域。堆内存的大小直接影响到JVM的性能和稳定性。

设置初始堆大小和最大堆大小:使用-Xms和-Xmx参数分别设置JVM启动时的初始堆大小和可使用的最大堆大小。这两个值应该根据应用程序的内存需求来确定,以避免频繁的GC和OOM(OutOfMemoryError)错误。
调整新生代和老年代的比例:新生代用于存放新生成的对象,老年代用于存放经过多次GC后仍然存活的对象。可以通过-XX:NewRatio参数调整新生代和老年代的比例,或者通过-Xmn参数直接设置新生代的大小。
设置Survivor区的大小:Survivor区是新生代中用于存放经过一次GC后仍然存活的对象的空间。可以通过-XX:SurvivorRatio参数调整Eden区和Survivor区的大小比例。

9、Java中的锁

Java中的锁是一种用于实现多线程同步和互斥的机制,以防止多个线程同时访问共享资源导致的数据不一致问题。

Java中锁的分类
(1)synchronized关键字:用于修饰方法或代码块,实现独占锁和悲观锁,保证同一时间只有一个线程能访问临界资源。‌23
(2)ReentrantLock:实现了Lock接口,需要手动获取和释放锁,支持可重入和公平锁。‌4
(3)读写锁(Read/Write Locks):允许多个线程同时读取共享资源,但写入时需要独占访问。
(4)乐观锁与悲观锁:悲观锁在访问共享资源前先上锁,乐观锁通过版本号机制允许多个线程同时读取,但在更新时检查版本号。
(5)自旋锁、无锁、偏向锁、轻量级锁、重量级锁:根据并发场景动态调整锁的表现形式,以最小化锁的开销。

10、什么是泛型擦除?
在编译过程中,Java编译器会对泛型类型进行类型检查,并在必要时插入类型转换代码。但是,一旦编译器完成了类型检查和类型转换,它就会将泛型类型的信息擦除,将泛型类型替换为原始类型(raw type)或者它们的上界(bound)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值