JVM问题及解答

栏目: Java · 发布时间: 5年前

内容简介:常见JVM问题参考:Minor GC采用复制算法,将Eden区的对象复制到Suvivor空间,然后进行清除 Full Gc采用的是标记-压缩算法,让所有的对象都向一端移动,然后直接清理掉端边界以外的内存。

常见JVM问题

  1. JVM内存模型,GC机制和原理。 注意JVM内存模型与 Java 内存模型(JMM)不是同一个东西。 JVM = 类加载器(classloader) + 执行引擎(execution engine) + 运行时数据区域(runtime data area)
    JVM问题及解答
  • PC寄存器:保存JVM正在执行的字节码指令地址。如果是native的,那么pc寄存器的值为undefined
  • JVM Stack:存储局部变量与一些过程结果的地方。在方法调用和返回中也扮演了很重要的角色。
  • Heap:堆是可以可供各个线程共享的运行时存储区域,也是供所有类的实例和数组对象分配内存的区域。堆在JVM启动的时候创建。堆所存储的就是被GC所管理的各种对象。
  • Method Area:各个线程共享的运行时内存区,它存储每一个类的实例信息,运行时常量池,字段和方法数据,构造函数和普通方法的字节码等内容。还有一些特殊方法。
  • Run-Time Constant Pool:在方法区中分配,在加载类和接口到虚拟机之后,就创建对应的运行时常量池。
  • Native Method Stacks:JDK中native的方法,System类和Thread类中有很多。使用 C语言 编写的方法,这个也通常叫做C stack。
JVM问题及解答

参考: 多线程之Java内存模型(JMM)(一)

  1. GC分哪两种,Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?
  • 从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC。当Eden区满时,触发Minor GC。
  • Full GC 是清理整个堆空间—包括年轻代和老年代。Major GC通常是跟full GC是等价的,收集整个GC堆。
    • 调用System.gc时,系统建议执行Full GC,但是不必然执行,
    • 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小
    • 老年代空间不足
    • 通过Minor GC后进入老年代的平均大小大于老年代的可用内存

Minor GC采用复制算法,将Eden区的对象复制到Suvivor空间,然后进行清除 Full Gc采用的是标记-压缩算法,让所有的对象都向一端移动,然后直接清理掉端边界以外的内存。

参考: Java的垃圾回收机制-垃圾收集算法(一)

  1. JVM里的有几种classloader,为什么会有多种? JDK中默认情况下有三种,如下图
    JVM问题及解答
  • BootStrap ClassLoader,负责加载/lib或被-Xbootclasspath指定路径下的类库,开发者不可以直接使用
  • Extension ClassLoader,负责加载/lib/ext或被java.ext.dirs系统变量指定的路径中的所有类库,开发者可以直接使用
  • App ClassLoader,这个类加载器是ClassLoader.getSystemClassLoader()的返回值,负责加载用户类路径上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序没有自定义过类加载器,那么系统默认使用这个类加载器。

如果一个类收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委派给父类来实现,每一个层次的类加载器都是这样,因此所有的类加载请求都会最终传送到启动类加载器,只有当父类加载器无法完成这个加载请求,子类加载器才会自己尝试加载。

好处:避免内存中出现同样的字节码。可以很好的解决各个类加载器的基础类统一问题。

参考:JVM是如何加载类的?

  1. 什么情况下我们需要破坏双亲委派模型? 热替换,热部署。OSGI是Java业界广泛认可的模块化标准,而OSGI模块化热部署的关键是它自定义的类加载器。每一个模块都有一个自己的类加载器,当需要更换一个 Bundle(包) 时,Bundle连同类加载器一同替换实现代码热部署。

弄懂了OSGi的精髓,就可以算是掌握了类加载器的精髓

参考:JVM是如何加载类的?

  1. 常见的JVM调优方法有哪些?可以具体到调整哪个参数,调成什么值? 主要调节吞吐量和响应时间: 参考:记一次JVM调优 如何解决OutOfMemoryError

  2. JVM class文件结构是如何解析的;

  3. 可见性,重排序,final关键字 可见性是指一个线程修改某个共享变量的值的时候,其它线程能立刻得知。 重 排序 是底层做的优化,有些代码会在机器层面上提前执行,从而出现不正常的结果 final在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。

参考:深入理解final关键字 8. Java对象模型 每一个Java类,在被JVM加载的时候,JVM会给这个类创建一个instanceKlass,保存在方法区,用来在JVM层表示该Java类。当我们在Java代码中,使用new创建一个对象的时候,JVM会创建一个instanceOopDesc对象,这个对象中包含了两部分信息,对象头以及元数据。对象头中有一些运行时数据,其中就包括和多线程相关的锁的信息。元数据其实维护的是指针,指向的是对象所属的类的instanceKlass。

这个内容比较多,需要深入理解

参考:Java对象模型

  1. oop-klass

  2. 对象存活判定 可达性分析算法:可达性分析,通过一系列"GC Roots"的对象作为起始点,往下走,一个对象到GC roots没有任何引用的时候,则证明对象是不可用的 可作为GC roots的对象:

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中JNI引用的对象
  1. Java的引用类型
  • 强引用:正常对象赋值的语句,String a = "abc";强引用可以直接访问目标对象,并且不会被系统回收,强引用可能导致内存泄漏
  • 软引用:比强引用稍微弱一点的类型,只有再内存不足的情况下才会被回收。如果再内存足够的时候,调用System.gc()也不会回收软引用的对象。
  • 弱引用:比软引用弱一点的引用类型,只要发现弱引用,都会将对象进行回收。
  • 虚引用:最弱的一个引用类型,一个持有虚引用的对象,和没有引用几乎是一样的。虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收的过程。

参考: Java Primitive type与References type


以上所述就是小编给大家介绍的《JVM问题及解答》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Effective JavaScript

Effective JavaScript

David Herman / Addison-Wesley Professional / 2012-12-6 / USD 39.99

"It's uncommon to have a programming language wonk who can speak in such comfortable and friendly language as David does. His walk through the syntax and semantics of JavaScript is both charming and h......一起来看看 《Effective JavaScript》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具