Ryan's Blog

Jvm的运行时内存区域是怎样的?

JVM的运行时内存区域是怎样的? 典型回答 根据Java虚拟机规范的定义,JVM的运行时内存区域主要由Java堆、虚拟机栈、本地方法栈、方法区和程序计数器以及运行时常量池组成。其中堆、方法区以及运行时常量池是线程之间共享的区域,而栈(本地方法栈+虚拟机栈)、程序计数器都是线程独享的。 需要注意的是,上面的这6个区域,是虚拟机规范中定义的,但是在具体的实现上,不同的虚拟机,甚至是同一个虚拟...

Jvm有哪些垃圾回收算法?

JVM有哪些垃圾回收算法? 典型回答 标记-清除 标记清除是最简单和干脆的一种垃圾回收算法,他的执行流程是这样子的:当 JVM 识别出内存中的垃圾以后,直接将其清除,但是这样有一个很明显的缺点,就是会导致内存空间的不连续,也就是会产生很多的内存碎片。先画个图来看下 我们使用上图左边的图来表示垃圾回收之前的样子,黑色的区域表示可以被回收的垃圾对象。这些对象在内存空间中不是连续的。右侧这...

Jvm是如何创建对象的?

JVM是如何创建对象的? 典型回答 首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程 分配内存。JVM会在堆中为对象分配内存空间(无JIT优化情况下)。在HotSpot中,对象的内存分配有两种方式,分别是指针碰撞和空闲列表法。 指针碰撞:当堆中...

Jvm如何判断对象是否存活?

JVM如何判断对象是否存活? 典型回答 当JVM判断对象不再存活的时候,便会在下一次GC时候将该对象回收掉,为堆腾出空间,那么JVM如何判断对象是否存活呢? JVM有两种算法来判断对象是否存活,分别是引用计数法和可达性分析算法 引用计数法:给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使...

Jvm如何保证给对象分配内存过程的线程安全?

JVM如何保证给对象分配内存过程的线程安全? 典型回答 首先,我们先来梳理下,JVM是如何给对象分配内存的: 如果JIT的逃逸分析后该对象没有逃逸,那么可能优化到栈上分配。 否则对象主要分配到新生代上,如果启动了TLAB,则分配到TLAB中。 如果被判断为大对象,则直接分配到直接进入老年代,譬如很长的字符串和数组,避免为大对象分配内存时由于分配担保机制带来的复制而降低效率 ...

Jvm为什么要把堆和栈区分出来呢?

JVM为什么要把堆和栈区分出来呢? 典型回答 堆和栈是JVM中的两个区域,想要知道为什么要搞两个区域,其实只需要搞清楚他们的特点和用途之间区别是什么就行了。 堆是存储对象的区域,堆的大小可以根据需要随时调整,堆的管理有垃圾回收器进行,堆内存是多个线程之间共享的。 栈是每个线程独享的一块区域,用于方法调用、局部变量等的存储。 把这两者区分开的好处有以下几个: 首先因为他们的存储内容...

Jdk1.8和1.9中类加载器有哪些不同

JDK1.8和1.9中类加载器有哪些不同 典型回答 从Java虚拟机的角度来讲,只存在两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现(只限于HotSpot),是虚拟机自身的一部分; 另一种就是所有其他的类加载器,这些类加载器都由Java语言实现,独立于虚拟机外部,并且全都继承自抽象类java.lang.ClassLo...