基于前面三篇关于jvm的理解,再次进一步研究jvm的其它特性:
一、什么是JVM
JVM(Java Virtual Machine),Java虚拟机,它是JRE的一部分,通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM的内部体系结构分为三部分:类装载器(ClassLoader)子系统,运行时数据区,和执行引擎。
- 类加载器:每一个JVM都有一个类加载器子系统,负责将程序加载到JVM中,并赋予加载的类或者接口唯一名字。JVM包含两大类类加载器:启动类装载器和用户自定义类装载器。启动类装载器是JVM实现的一部分,用户自定义类装载器则是Java程序的一部分,必须是ClassLoader类的子类。
- 执行引擎:负责执行字节码或者执行本地方法。
- 运行时数据区:主要包括方法区,堆,栈,PC寄存器,本地方法栈。
二、JVM管理的内存结构
JVM在执行Java程序的时候,会把管理的数据区划分为若干个不同的区域,根据《Java虚拟机规范》,JVM管理的内存区分为PC寄存器(程序计数器)、Java虚拟机栈、本地方法栈、Java堆、方法区以及运行时常量池。注意一点,这些区域只是逻辑划分,在物理上都属于内存。
三、不同的虚拟机在实现JVM的时候有什么不同
根据《Java虚拟机规范》描述,不同的虚拟机对于方法区的管理最为宽松。方法区在虚拟机启动的时候创建,是堆的逻辑组成部分,规范不限定实现方法区的内存位置和代码编译的管理策略。方法区的容量可以是固定的,也可以随着程序执行的需求动态扩展,并在不需要过多的空间时自行收缩。方法区在实际内存空间站可以是不连续的,简单的虚拟机实现可以选择在这个区域不实现垃圾收集与压缩。
在hotspot的JVM实现中,方法区仅是逻辑上的独立区域,在物理上并没有独立于堆而存在,而是位于永久代中。所以,这时候方法区也是可以被垃圾回收的。在Java 8中 ,HotSpot虚拟机移除了永久代,使用本地内存来存储类元数据信息并称之为:元空间(Metaspace)
四、Java中堆栈的区别
堆和栈是完全不同的两块内存区域,二者之间最大的区别就是存储的内容不同:堆中主要存放对象实例;栈(局部变量表)中主要存放各种基本数据类型、对象的引用。
五、对象内存一定在堆上创建么
Java对象的创建方式有:通过关键字new,克隆对象,反射机制,通过Constructor类的newInstance,反序列化等。普通对象创建大致会经过如下几个过程:
- 虚拟机遇到new指令,到常量池定位到这个类的符号引用
- 检查符号引用代表的类是否被加载、解析、初始化过
- 虚拟机为对象分配内存
- 虚拟机将分配到的内存空间都初始化为零值
- 虚拟机对对象进行必要的设置。
- 执行方法,成员变量进行初始化。
通常,对象内存的分配是在堆上的,但随着JIT编译期的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些对象可能被分配到对应线程的栈上。
六、除了JVM运行时内存以外,还有什么区域可以用吗
虚拟机运行时数据区以外,直接内存也被用于Java程序,直接内存的分配不受Java堆大小的限制。在JDK 1.4中引入的NIO中,引入了一种基于Channel和Buffer的I/O方式,可以使用Native函数直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的应用进行操作。
七、Java中四种引用类型的进一步说明
- 强引用(Strong Reference):通常通过new创建一个新对象时返回的引用就是强引用。若一个对象通过一系列强引用可到达,它就是强可达的(strongly reachable),那么它就不被回收;当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
- 软引用(Soft Reference):如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
- 弱引用(Weak Reference):软引用和弱引用的区别在于,若一个对象是弱引用可达,无论当前内存是否充足它都会被回收,软引用要比弱引用“强”一些。如果这个对象是偶尔的使用,并且希望在使用时随时就能获取到,但又不想影响此对象的垃圾收集,那么你应该用 Weak Reference 来记住此对象。 当你想引用一个对象,但是这个对象有自己的生命周期,你不想介入这个对象的生命周期,这时候你就是用弱引用。
- 虚引用(Phantom Reference):虚引用是Java中最弱的引用,并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用存在的唯一作用就是当它指向的对象被回收后,虚引用本身会被加入到引用队列中,用作记录它指向的对象已被销毁。
参考来源:https://juejin.im/post/5d4789afe51d453b386a62ac
https://blog.youkuaiyun.com/qq_41701956/article/details/80020103