JVM
文章平均质量分 85
喵先森爱吃鱼
这个作者很懒,什么都没留下…
展开
-
第十五章 垃圾回收相关算法
引用(指针) P指向了对象 A,A 中有一个属性又指向了对象 B,对象 B 中又有一个属性指向了对象 C,恰好对象 C 中又有一个属性指向了对象 A,即上图所示情况,对象 A、B、C 中的引用计数器分别为 2(分别是引用 P 和对象 C 中的属性),1,1。因此,基于老年代垃圾回收的特性,需要使用其他的算法。将活着的内存空间分为两块,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制到未被使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,最后完成垃圾回收。原创 2024-07-04 10:51:41 · 869 阅读 · 0 评论 -
第十四章 垃圾回收概述
现在,除了 Java 以外,C#,Python、Ruby 等语言都是用了自动垃圾回收的思想,也是未来发展趋势。可以说,这种自动化的内存分配和垃圾回收的方式已经成为现代开发语言必备的标准。原创 2024-07-04 10:51:07 · 295 阅读 · 0 评论 -
第十三章 StringTable
如果不是用双引号声明的 String 对象,可以使用 String 提供的 intern 方法:intern 方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。比如:String myInfo = new String(“I love atguigu”).intern();也就是说,如果在任意字符上调用 String.intern 方法,那么其返回结果所指向的那个类实例,必须和直接以常量形式出现的字符串实例完全相同。原创 2024-07-04 10:50:37 · 440 阅读 · 0 评论 -
第十二章 执行引擎
解释器:当 Java 虚拟机启动时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容“翻译”为对应平台的本地机器指令执行。JIT(Just In Time Compiler)编译器:就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言。一般来讲,JIT 编译出来的机器码性能比解释器高C2 编译器启动时长比 C1 编译器慢,系统稳定执行以后,C2 编译器执行速度远远快于 C1 编译器。自 JDK 10 起,HotSpot 又加入一个全新的即时编译器:Graal 编译器。原创 2024-07-04 10:49:32 · 602 阅读 · 0 评论 -
第十一章 直接内存(Direct Memory)
读写文件,需要与磁盘交互,需要由用户态切换到内核态。在内核态时,需要内存如下图的操作。这里需要两份内存存储重复数据,效率低。使用 NIO 时,如下图。操作系统划出的直接缓存区可以被 Java 代码直接访问,只有一份。NIO 适合对大文件的读写操作。原创 2024-07-04 10:48:55 · 308 阅读 · 0 评论 -
第十章 对象的实例化内存布局与访问定位
它并不是一种具体的、固定不变的数据类型或实体,而是代表了程序设计中的一个广义的概念。句柄一般是指获取另一个对象的方法——一个广义的指针,它的具体形式可能是一个整数、一个对象或就是一个真实的指针,而它的目的就是建立起与被访问对象之间的唯一的联系。这两种对象访问方式各有优势,使用句柄来访问的最大好处就是 reference 中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为,如从 S0 区向 S1 区复制对象)时只会改变句柄中实例数据指针,而 reference 本身不需要修改。原创 2024-07-04 10:48:10 · 595 阅读 · 0 评论 -
第九章 方法区
Person 类的 .class 对应的运行时类本身要存放到方法区new 的 Person 对象需要放到堆空间中变量 person 需要放在 Java 虚拟机栈中《Java 虚拟机规范》中明确说明:“尽管所有的方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。”但对于 HotSpot JVM 而言,方法区还有一个别名叫做 Non-Heap (非堆),目的就是要和堆分开。所以,方法区看作是一块独立于 Java 堆的内存空间。OOM 演示:测试结果:使用“-原创 2024-07-04 10:47:35 · 942 阅读 · 0 评论 -
第八章 堆
为新对象分配内存是一件非常严谨和复杂的任务,JVM 的设计者们不仅需要考虑内存如何分配、在哪里分配等问题,并且由于内存分配算法与内存回收算法密切相关,所以还需要考虑 GC 执行完内存回收后是否会在内存空间中产生内存碎片。new 的对象先放伊甸园区。此区有大小限制。当伊甸园区的空间填满时,程序又需要创建对象,JVM 的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不在被其他对象所引用的对象进行销毁。再加载新的对象放到伊甸园区。然后将伊甸园区中的剩余对象移动到幸存者 0 区。原创 2024-07-04 10:47:00 · 929 阅读 · 0 评论 -
第七章 本地方法栈
Java 虚拟机栈用于管理 Java 方法的调用,而本地方法栈用于管理本地方法的调用。本地方法栈,也是线程私有的允许被实现成固定或者可动态扩展的内存大小。(在内存溢出方面是相同的)如果线程请求分配的栈容量超过本地方法栈允许的最大容量,Java 虚拟机将会抛出一个 StackOverflowError 异常。如果本地方法栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的本地方法栈,那么 Java 虚拟机将会抛出一个 OutOfMemoryErr原创 2024-07-04 10:46:16 · 257 阅读 · 0 评论 -
第六章 本地方法接口
简单地讲,一个 Native Method 就是一个 Java 调用非 Java 代码的接口。一个 Native Method 是这样一个 Java 方法:该方法的实现由非 Java 语言实现,比如 C。这个特征并非 Java 所特有,很多其他的编程语言都有这一机制,比如在 C++ 中,你可以用 extern “C” 告知 C++ 编译器去调用一个 C 的函数。原创 2024-07-04 10:45:44 · 341 阅读 · 0 评论 -
第五章 虚拟机栈
参数表分配完毕之后,再根据方法体内定义的变量的顺序和作用域分配。我们知道类变量表有两次初始化的机会,第一次是在“准备阶段”,执行系统初始化,对类变量设置零值,另一次则是在“初始化”阶段,赋予程序员在代码中定义的初始值。和类变量初始化不同的是,局部变量表不存在系统初始化的过程,这意味着一旦定义了局部变量则必须人为的初始化,否则无法使用。原创 2024-07-04 10:45:08 · 848 阅读 · 0 评论 -
第四章 程序计数器(PC寄存器)
它是一块很小的内存空间,几乎可以忽略不计。也是运行速度最快的存储区域。在 JVM 规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的 Java 方法的 JVM 指令地址;或者,如果是在执行 native 方法(本地方法,C/C++),则是未指定值(undefined)。它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。原创 2024-07-04 10:44:28 · 1521 阅读 · 0 评论 -
第三章 运行时数据区概述及线程
内存是非常重要的系统资源,是硬盘和 CPU 的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。JVM 内存布局规定了 Java 在运行过程中内存申请、分配、管理的策略,保证了 JVM 的高效稳定运行。不同的 JVM 对于内存的划分方式和管理机制存在着部分差异。Java 虚拟机定义了若干种程序运行期间会使用的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些则是与线程一一对应的,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁。原创 2024-07-04 10:43:23 · 304 阅读 · 0 评论 -
第二章 类加载子系统
在 Java 的日常应用程序开发中,类的加载几乎是由上述 3 中类加载器相互配合执行的,在必要时,我们还可以自定义类加载器,来定制类的加载方式。隔离加载类修改类加载的方式扩展加载源防止源码泄露开发人员可以通过继承抽象类 java.lang.ClassLoader 类的方式,实现自己的类加载器,以满足一些特殊的需求。原创 2024-07-04 10:39:53 · 326 阅读 · 0 评论 -
第一章 JVM 与 Java 体系结构
Java 虚拟机是一台执行 Java 字节码的虚拟计算机,它拥有独立的运行机制,其运行的 Java 字节码也未必由 Java 语言编译而成。JVM 平台的各种语言可以共享 Java 虚拟机带来的跨平台性、优秀的垃圾回收器,以及可靠的即时编译器。Java 技术的核心就是 Java 虚拟机(JVM,Java Virtual Machine),因为所有的 Java 程序都运行在 Java 虚拟机内部。原创 2024-07-04 10:38:21 · 329 阅读 · 0 评论