181. redis 淘汰策略有哪些?

• volatile-lru:从已设置过期时间的数据集(server. db[i]. expires)中挑选最近最少使用的数据淘汰。
• volatile-ttl:从已设置过期时间的数据集(server. db[i]. expires)中挑选将要过期的数据淘汰。
• volatile-random:从已设置过期时间的数据集(server. db[i]. expires)中任意选择数据淘汰。
• allkeys-lru:从数据集(server. db[i]. dict)中挑选最近最少使用的数据淘汰。
• allkeys-random:从数据集(server. db[i]. dict)中任意选择数据淘汰。
• no-enviction(驱逐):禁止驱逐数据。

182. redis 常见的性能问题有哪些?该如何解决?

• 主服务器写内存快照,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以主服务器最好不要写内存快照。
• Redis 主从复制的性能问题,为了主从复制的速度和连接的稳定性,主从库最好在同一个局域网内。

183. 说一下 jvm 的主要组成部分?及其作用?

• 类加载器(ClassLoader)
• 运行时数据区(Runtime Data Area)
• 执行引擎(Execution Engine)
• 本地库接口(Native Interface)
组件的作用: 首先通过类加载器(ClassLoader)会把 Java 代码转换成字节码,运行时数据区(Runtime Data Area)再把字节码加载到内存中,而字节码文件只是 JVM 的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。

184. 说一下 jvm 运行时数据区?

Java虚拟机在执行Java程序的过程中会把它管理的内存分为若干个不同的数据区域。这些区域有着各自的用途,一级创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。根据《Java虚拟机规范》中规定,jvm所管理的内存大致包括以下几个运行时数据区域,如图所示:

1.程序计数器
  占据一块较小的内存空间,可以看做当前线程所执行的字节码的行号指示器。在虚拟机概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能都需要依赖这个计数器来完成。

由于jvm的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令。因此未来线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们成这类内存区域为“线程私有”的内存。

如果线程正在执行的是一个Java方法,这个计数器记录的则是正在执行的虚拟机字节码指令的地址;

如果正在执行的是Native方法,这个计数器则为空(undefined)。

此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

2.Java虚拟机栈
  线程私有,生命周期和线程相同,虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧 用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用直至完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

局部变量表存放了编译期可知的各种基本类型数据(boolean、byte、char、short、int、float、long、double)、对象引用、returnAddress类型(指向了一条字节码指令的地址)。

其中64位长度的long和double类型的数据会占用2个局部变量表空间(slot),其余的数据类型只占用1个。局部变量表所需的内存空间在编译期完成分配,当进入一个方法时,这个方法所需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

在Java虚拟机规范中,对此区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将会抛出Stack OverflowError异常;如果虚拟机栈可以动态扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

3.本地方法栈
  本地方法栈与虚拟机栈所发挥的作用非常相似,他们之间的区别不过是虚拟机栈为虚拟机执行Java方法(字节码)服务,而本地方法栈则为虚拟机中使用到的native方法服务。在虚拟机规范中对本地方法栈中方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机直接把本地方法栈和虚拟机栈合二为一,与虚拟机栈一样也会抛出Stack OverflowError异常和OutOfMemoryError异常。

4.Java堆
  对于大多数应用来说,堆空间是jvm内存中最大的一块。Java堆是被所有线程共享,虚拟机启动时创建,此内存区域唯一的目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配,但是随着JIT编译器的发展和逃逸分析技术逐渐成熟,栈上分配,标量替换优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上也就变得不那么绝对了。

Java堆是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆”。从内存回收角度看,由于现在收集器基本都采用分代收集算法,所以Java堆还可以细分为:新生代和老年代;再细致一点的有Eden空间,From Survivor空间,To Survivor空间等。从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区。不过无论如何划分,都与存放内容无关,无论哪个区域,存储的都仍然是对象实例,进一步划分的目的是为了更好的回收内存,或者更快的分配内存。(如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。)

5.方法区(也有人叫永久代)
  和堆一样所有线程共享,主要用于存储已被jvm加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

(在JDK1.7发布的HotSpot中,已经把字符串常量池移除方法区了。)

6.常量池:
  运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

Java虚拟机对class文件每一部分的格式都有严格规定,每一个字节用于存储哪种数据都必须符合规范才会被jvm认可。但对于运行时常量池,Java虚拟机规范没做任何细节要求。

运行时常量池有个重要特性是动态性,Java语言不要求常量一定只在编译期才能产生,也就是并非预置入class文件中常量池的内容才能进入方法区的运行时常量池,运行期间也有可能将新的常量放入池中,这种特性使用最多的是String类的intern()方法。

既然运行时常量池是方法区的一部分,自然受到方法区内存的限制。当常量池无法再申请到内存时会抛出outOfMemeryError异常。

185. 说一下堆栈的区别?

  1. 栈内存存储的是局部变量而堆内存存储的是实体;
  2. 栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;
  3. 栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

186. 队列和栈是什么?有什么区别?

• 队列和栈都是被用来预存储数据的。
• 队列允许先进先出检索元素,但也有例外的情况,Deque 接口允许从两端检索元素。
• 栈和队列很相似,但它运行对元素进行后进先出进行检索。

187. 什么是双亲委派模型?

在介绍双亲委派模型之前先说下类加载器。对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立在 JVM 中的唯一性,每一个类加载器,都有一个独立的类名称空间。类加载器就是根据指定全限定名称将 class 文件加载到 JVM 内存,然后再转化为 class 对象。
类加载器分类
1 启动类加载器(JVM的各提供商使用本地代码来实现Bootstrap类加载器)

启动类加载器(BootstrapClassLoader)引导类装入器是用本地代码实现的类装入器,它负责将 /lib下面的核心类库或-Xbootclasspath选项指定的jar包加载到内存中。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

启动类加载器是最低层的加载器,它是由C++编写的,因为加载器是一个类,也需要通过类加载器加载,启动类加载器就能完成这个功能。

2 扩展类加载器

扩展类加载器(ExtensionClassLoader)是由ExtClassLoader类实现的。它负责将< Java_Runtime_Home >/lib/ext或者由系统变量-Djava.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。

3 系统类加载器
系统类加载器(SystemClassLoader)是由AppClassLoader类实现。它负责将系统类路径java -classpath或-Djava.class.path变量所指的目录下的类库
加载到内存中。还用于加载入口函数类(仅含有main()方法的类)。开发者可以直接使用系统类加载器。

双亲委派模型:如果一个类加载器收到了类加载的请求,它首先不会自己去加载这个类,而是把这个请求委派给父类加载器去完成,每一层的类加载器都是如此,这样所有的加载请求都会被传送到顶层的启动类加载器中,只有当父加载无法完成加载请求(它的搜索范围中没找到所需的类)时,子加载器才会尝试去加载类。

188. 说一下类加载的执行过程?

类加载分为以下 5 个步骤:
1. 加载:根据查找路径找到相应的 class 文件然后导入;
2. 检查:检查加载的 class 文件的正确性;
3. 准备:给类中的静态变量分配内存空间;
4. 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;
5. 初始化:对静态变量和静态代码块执行初始化工作。

189. 怎么判断对象是否可以被回收?

一般有两种方法来判断:
引用计数器:为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题;
可达性分析:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。

190. java 中都有哪些引用类型?

1 强引用
Java中默认声明的就是强引用,比如:

Object obj = new Object(); //只要obj还指向Object对象,Object对象就不会被回收
obj = null;  //手动置null

只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了

2 软引用
软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。

3 弱引用
弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。在 JDK1.2 之后,用 java.lang.ref.WeakReference 来表示弱引用。

4 虚引用
虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。引用队列可以与软引用、弱引用以及虚引用一起配合使用,当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。

191. 说一下 jvm 有哪些垃圾回收算法?

• 标记-清除算法
• 标记-整理算法
• 复制算法
• 分代算法

192. 说一下 jvm 有哪些垃圾回收器?

• Serial:最早的单线程串行垃圾回收器。
• Serial Old:Serial 垃圾回收器的老年版本,同样也是单线程的,可以作为 CMS 垃圾回收器的备选预案。
• ParNew:是 Serial 的多线程版本。
• Parallel 和 ParNew 收集器类似是多线程的,但 Parallel 是吞吐量优先的收集器,可以牺牲等待时间换取系统的吞吐量。
• Parallel Old 是 Parallel 老生代版本,Parallel 使用的是复制的内存回收算法,Parallel Old 使用的是标记-整理的内存回收算法。
• CMS:一种以获得最短停顿时间为目标的收集器,非常适用 B/S 系统。
• G1:一种兼顾吞吐量和停顿时间的 GC 实现,是 JDK 9 以后的默认 GC 选项。

193. 详细介绍一下 CMS 垃圾回收器?

CMS 是英文 Concurrent Mark-Sweep 的简称,是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上,这种垃圾回收器非常适合。在启动 JVM 的参数加上“-XX:+UseConcMarkSweepGC”来指定使用 CMS 垃圾回收器。
CMS 使用的是标记-清除的算法实现的,所以在 gc 的时候回产生大量的内存碎片,当剩余内存不能满足程序运行要求时,系统将会出现 Concurrent Mode Failure,临时 CMS 会采用 Serial Old 回收器进行垃圾清除,此时的性能将会被降低。

194.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

• 新生代回收器:Serial、ParNew、Parallel Scavenge
• 老年代回收器:Serial Old、Parallel Old、CMS
• 整堆回收器:G1
新生代垃圾回收器一般采用的是复制算法,复制算法的优点是效率高,缺点是内存利用率低;老年代回收器一般采用的是标记-整理的算法进行垃圾回收。

195. 简述分代垃圾回收器是怎么工作的?

分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3。
新生代使用的是复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,它的执行流程如下:
• 把 Eden + From Survivor 存活的对象放入 To Survivor 区;
• 清空 Eden 和 From Survivor 分区;
• From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor。
每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。大对象也会直接进入老生代。
老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记整理的执行算法。以上这些循环往复就构成了整个分代垃圾回收的整体执行流程。

196. 说一下 jvm 调优的工具?

JDK 自带了很多监控工具,都位于 JDK 的 bin 目录下,其中最常用的是 jconsole 和 jvisualvm 这两款视图监控工具。
• jconsole:用于对 JVM 中的内存、线程和类等进行监控;
• jvisualvm:JDK 自带的全能分析工具,可以分析:内存快照、线程快照、程序死锁、监控内存的变化、gc 变化等。

197. 常用的 jvm 调优的参数都有哪些?

• -Xms2g:初始化推大小为 2g;
• -Xmx2g:堆最大内存为 2g;
• -XX:NewRatio=4:设置年轻的和老年代的内存比例为 1:4;
• -XX:SurvivorRatio=8:设置新生代 Eden 和 Survivor 比例为 8:2;
• –XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合;
• -XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器组合;
• -XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组合;
• -XX:+PrintGC:开启打印 gc 信息;
• -XX:+PrintGCDetails:打印 gc 详细信息。

198.什么情况下会发生栈内存溢出。

栈是线程私有的,他的生命周期与线程相同,每个方法在执行的时候都会创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口等信息。局部变量表又包含基本数据类型,对象引用类型
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常,方法递归调用产生这种结果。
如果Java虚拟机栈可以动态扩展,并且扩展的动作已经尝试过,但是无法申请到足够的内存去完成扩展,或者在新建立线程的时候没有足够的内存去创建对应的虚拟机栈,那么Java虚拟机将抛出一个OutOfMemory 异常。(线程启动过多)

199.怎么打出线程栈信息。

  1. 输入jps,获得进程号。
  2. top -Hp pid 获取本进程中所有线程的CPU耗时性能
  3. jstack pid命令查看当前java进程的堆栈状态
  4. 或者 jstack -l > /tmp/output.txt 把堆栈信息打到一个txt文件。
  5. 可以使用fastthread堆栈定位,fastthread.io/

200. 如何判断是否有内存泄露?

泄露可以对比不同时间点内存分配,一般看用户类型的分配情况,什么在增加。具体,比如用jmap -histo:live 多次快照,然后对比差异,或者用jmc之类profiling工具,都可以进行,对比会更加流畅一些
定位 Full GC 发生的原因,有哪些方式?
1,首先通过printgcdetail 查看fullgc频率以及时长
2,通过dump 查看内存中哪些对象多,这些可能是引起fullgc的原因,看是否能优化
3,如果堆大或者是生产环境,可以开起jmc 飞行一段时间,查看这期间的相关数据来订位问题

JAVA知识两百问(181~200)相关推荐

  1. java知识精华总结

    Java 知识--精华总结 一. -java 概述与基础知识-6 1.何为编程?-6 2.Java 语言概述,历史.特点- 6 3.什么是跨平台性?原理是什么?JVM- 7 4.Jre 和 Jdk 的 ...

  2. Java知识——精华总结

    Java知识--精华总结 一.java概述与基础知识 1.何为编程? 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程. 为了使计算机能够理解人的意图,人类就必须 ...

  3. 黑马程序员入学Java知识——精华总结

    黑马程序员入学Java知识--精华总结 J2SE部分,Java高新技术部分,7K面试题部分等黑马入学要求的知识点总结! 一.黑马程序员-java概述与基础知识 6 1.何为编程? 6 2.Java语言 ...

  4. 阿里二面准备(Java 研发),精心准备200题(含答案)收割 offer

    这篇文章我花了两天编辑,是目前我能找到的几乎所有的问题.所以你们如果能全部掌握,基本就能收割 offer 了.时间有限的话,针对自己的情况优先选最有可能被问到的问题来准备. 文中的200道题大部分都包 ...

  5. 你应该更新的Java知识之常用程序库

    些库有的解决了平时常见又重要的问题,有的则让Coding变得更惬意,值得全速跟进了解! 原文 在很多人眼中,Java已经是一门垂垂老矣的语言,但并不妨碍Java世界依然在前进.如果你曾离开Java,云 ...

  6. java 切面获取参数_每天分享一点Java知识(spring-aop)

    每天分享一点Java知识,码字不易,喜欢的可以关注一波,共同学习.20191127 本篇将详细讲解SpringAOP的概念以及如何实现. 1. 何为AOP AOP:面向切面编程,相对于OOP面向对象编 ...

  7. Java面试常问计算机网络问题

    转载自   Java面试常问计算机网络问题 一.GET 和 POST 的区别 GET请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:/test/demo_form.asp?na ...

  8. 最全面的Java面试题-----是你更好的掌握java知识

    最全面的Java面试题-----是你更好的掌握java知识 目录 l     概念题--- 1 一.        JAVA基础--- 1 1)      面向对象的特征--- 1 2)      什 ...

  9. Java毕设答辩会问些什么?

    大家好,今天我们谈论的话题是Java毕设答辩会问些什么.Java作为一门广泛应用于软件开发的语言,被广泛运用于毕业设计中.在毕设答辩会上,老师们会对学生们的毕设进行提问和评估.那么,老师们通常会问些什 ...

最新文章

  1. cms php vue 开源_骑士CMS文件包含+getshell
  2. mysql数据库更新表_Mysql数据库(四)表记录的更新操作
  3. 备战“双11”,阿里云为企业提供一站式资源保障服务
  4. JQ基础练习---图片划过变暗
  5. javascript的事件冒泡,阻止事件冒泡和事件委托, 事件委托是事件冒泡的一个应用。...
  6. java获取本周的开始时间和结束时间_创业板注册制开始时间/股票开户流程结束后,怎么炒股?...
  7. 2019下半年系统集成项目管理工程师上午真题
  8. 一位Oracle顶流铁粉的“躬身入局”
  9. PowerDesigner中的CDM设计的外键作主键的问题
  10. Linux常用命令——cd
  11. 部署django应用
  12. ubuntu gif 制作工具
  13. MEM/MBA 写作-论说文(02)立意 知识练习
  14. SPEA2_Python
  15. matlab 狄利克雷函数代码,狄利克雷函数
  16. dolphinscheduler海豚调度是什么?
  17. 这些选择器你都知道吗?
  18. c语言实验设备管理系统设计作业,C语言课程设计实验设备管理系统设计
  19. 使用xib自定义button
  20. Java实现拼图小游戏(7)—— 计步功能及菜单业务的实现

热门文章

  1. 微博数据分析工具限时福利!购买西瓜微数加送会员时长 ,最多加赠1个月!
  2. python英语词汇读音_利用PYTHON 爬虫爬出自己的英语单词库
  3. ODOO 进出口外贸行业解决方案
  4. android系统APK签名生成大全
  5. Netty-入门篇(核心组件介绍实战)
  6. linux 终端隐藏光标,如何在gnome-terminal中禁用闪烁的光标?
  7. swiper轮播-可支持触摸滑动(整理)
  8. 什么是短视频电商,短视频电商的商业模式标题】
  9. 视频教程-Java进阶高手课-Spring精讲精练-Java
  10. nokia专业显示器测试软件,液晶显示器显示屏NOkia幕检测工具