JVM+JDK面试每日一题

JVM内存模型

在这里插入图片描述

metaspace为什么取代永久代?

永久代一般存储类的信息,用的类越多,永久代越满。永久代在项目开始时就固定大小,项目运行功能越久,gc越难。
metaspace存储在本地内存中,不在java虚拟机中。可以支持很大的开销16g。

  • 难以调优
  • 简化fullgc
  • 可以在gc不暂停的情况下释放类数据

jvm怎么加载类的?

在Java代码中,Class的加载、连接与初始化过程都是在程序运行期间完成的。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

GC如何判断对象可回收

  1. 引用计数法:增加引用计数器+1,减少引用-1,a=0时,回收
  2. 可达性分析算法:从gcroot向下搜索,当一个对象不与gcroot相连就可判定回收

gcroot有哪些?

  1. java栈内的应用对象
  2. 方法区static属性引用对象
  3. 常量引用对象
  4. native引用对象

GC垃圾回收算法

垃圾回收算法主要有四个

  1. 复制算法:将内存分为两块,轮询发现不需要回收的放到另一块,两块内存总有一块是空的,好处是内存连续,但内存空间消耗大
  2. 标记清除法:轮询标记,需要回收的直接删除,但会造成内存不连续
  3. 标记压缩法:轮询标记,不需要回收的依次填到需要回收的地址上,内存连续但较慢
  4. 分代回收算法,根据不同代设置不同算法。
    elden,survivor1,survivor2:复制算法
    old,perm:标记清除或压缩

GC垃圾回收器

在这里插入图片描述

GC(Garbage Collection)垃圾回收器是Java虚拟机(JVM)中的一种内存管理机制,用于自动回收不再使用的对象,释放其占用的内存空间。GC垃圾回收器通常分为串行垃圾回收器、并行垃圾回收器、并发垃圾回收器、G1垃圾回收器等几种。

串行垃圾回收器:串行垃圾回收器是最简单的垃圾回收器,它只使用一个线程进行垃圾回收操作。适合单CPU环境下的小型应用程序。

并行垃圾回收器:并行垃圾回收器使用多个线程进行垃圾回收操作,提高了垃圾回收的效率,但会增加系统的负载。适合多CPU环境下的中型应用程序。

并发垃圾回收器:并发垃圾回收器在应用程序运行的同时进行垃圾回收操作,减少了GC停顿时间,但也会增加系统的负载。适合大型应用程序。

G1垃圾回收器:G1垃圾回收器是一种面向服务器的垃圾回收器,它将堆内存分为多个小块进行回收,可以在不同区域之间进行动态调整,从而提高了垃圾回收的效率和吞吐量,减少了GC停顿时间。

选择哪种垃圾回收器需要根据应用程序的特点、硬件配置和性能要求等因素来确定。在实际应用中,可以通过调整JVM参数来选择垃圾回收器类型和优化垃圾回收器性能。

如何解决线上gc频繁问题

线上GC频繁问题通常是由于内存占用过高而导致的,可以采取以下几种方法来解决:

调整JVM参数:通过调整JVM参数,如-Xms、-Xmx、-XX:NewSize、-XX:MaxNewSize、-XX:SurvivorRatio等,可以减少GC的频率和时间。具体的参数调整需要根据应用程序的内存使用情况和服务器硬件配置等因素来确定。

优化代码:尽量避免创建大量临时对象,使用对象池或重用对象等方式减少内存使用。避免使用大量的String操作和字符串连接,使用StringBuilder或StringBuffer等方式代替。避免使用大量的finalize方法,可以手动释放资源等。

使用缓存:将一些经常使用的数据缓存在内存中,减少频繁的查询和计算,可以使用缓存框架如Redis、Memcached等。

增加服务器内存:增加服务器内存可以减少GC的频率和时间,提高应用程序的性能。

使用分布式架构:使用分布式架构可以将应用程序分布在多个服务器上,减少单个服务器的负载,从而减少GC的频率和时间。

需要根据具体的应用程序和环境来确定采取哪些方法,可以结合监控和分析工具来进行调优和优化。

HashMap在扩容上做了哪些优化?

1.7之前扩容,map里的全部元素都需要refesh hash。
1.8之后,每次扩容为之前两倍,元素要么在原位置,要么在+len位。
为什么为两倍?
在这里插入图片描述
不为两倍容易hash冲突。
resize过程中可以均匀的把冲突节点分散到新的bucket。

HashMap有哪些线程安全方法

Collection.sychronizedMap()(sychronized锁)
ConcurrentHashMap(新的锁机制,拆分hashmao,cas)性能好但代码繁琐

ConcurrentHashMap底层原理
1.7segement+entry
在这里插入图片描述
在这里插入图片描述

高并发集合有哪些问题

ThreadLoacl原理,应用场景

ThreadLocal又叫本地线程变量,在多线程并发执行的过程中,我们可以将某个变量存入ThreadLocal中,那么这个变量就可以看作专属于是该线程的本地变量,并且不受其他线程的干扰,从而达到对变量的安全访问。

1.7之前,threadlocal属于独立的一个类,自行管理生命周期。当需要用到时,thread向threadlocal里绑定一个key,之后thread从threadlocal里取val。
1.8之后,ThreadLocal是Thread类中的内部类。默认情况下为null。调用threadlocal.set时创建threadlocalmap,ThreadLocalMap是ThreadLocal的内部静态类,而它的构成主要是用Entry来保存数据 ,而且还是继承的弱引用。在Entry内部使用ThreadLocal作为key,使用我们设置的value作为value。

theadllocal会存在一些oom问题。因为threadlocalkey是弱引用,会被gc回收,但threadlocalval是强引用,这就会产生key为null的val。同时,threadlocal和线程绑定,但是由于线程池的存在,一个线程不会马上被删除,这就导致threallcoal会无限增加,如果不主动关闭。因此调用完threadlocal后要主动remove。

应用场景
hostholder保存用户状态数据替代session。
在这里插入图片描述

sychoronized和lock有什么区别?

  1. sychronized是关键字,lock是接口。
  2. sychronized异常时自动释放锁,lock不能,所以lock要在trycatchfinnally中unlock
  3. sychronized不能响应中断,lock可以 sychronized不能知道有没有获取锁,lock.trylock可以
  4. readwritelock可以提高多线程读取效率。 lock性能较好
  5. sychronized使用wait,notify等调度机制,lock使用condition线程调度

什么是守护线程

死锁

  • 互斥条件:同一个资源同一个时间只能由一个线程进行访问
  • 不可剥夺条件:线程持有资源后,在释放之前,其他线程不能占有该资源
  • 请求和保持条件:线程等待过程中不会释放已持有的资源
  • 闭环条件:等待锁的线程应该形成闭环
    如何预防:
  • 加锁顺序(线程按照一定的顺序加锁)
  • 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
  • 死锁检测

线程池

sleep、wait、join、yield

线程安全活跃状态、竞态条件

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值