SEO技术

SEO技术

Products

当前位置:首页 > SEO技术 >

JVM运行时数据区详解:你了解它的哪些部分?

96SEO 2026-02-20 09:11 10


此章把运行时数据区当中较少的地方进行讲解

JVM运行时数据区详解:你了解它的哪些部分?

后续讲解虚拟机栈、堆、方法区这些地方

运行时数据区概述以及线程

前言

本章节主要讲述运行时数据区,是类加载之后的阶段

/>

当我们通过前面的:类的加载→链接(验证→准备→解析)→初始化,这几个阶段完成之后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用我们的运行时数据区

/>

类比一下大厨做饭,我们把运行时数据区比作大厨后面的东西(切好的菜品、厨具、调料等),而执行引擎就是烹饪的厨师。

运行时数据区结构

运行时数据区与内存

内存是非常重要的系统资源,是硬盘和CPU的中间仓库、桥梁,承载着操作系统和应用程序的实时运行。

JVM内存布局规定了Java在运行时内存申请、分配、管理的策略,保障了JVM的高效稳定运行。

不同的JVM对内存的划分方式和管理机制存在着部分差异。

我们通过磁盘和网络IO得到的数据都需要先加载到内存当中,然后CPU从内存当中获取数据进行读取

JDK8运行时数据区示意图:

/>

线程的内存空间

Java虚拟机定义了若干种程序运行期间或使用到的运行时数据区:其中一些随着虚拟机启动而创建,随着虚拟机退出而销毁。

另外一些则与线程一一对应,这些与线程一一对应的数据区随着线程的开始和结束而创建和销毁。

如下图,灰色为单独线程私有的,红色为多个线程共享的:

  • 线程独有:程序计数器、栈、本地方法栈

  • 线程共享:堆、堆外内存(永久代/元空间、代码缓存)

/>

Runtime类

每个JVM都只有一个Runtime实例

也就是运行时环境。

/>

线程

JVM线程

线程是一个程序当中的运行单元,JVM允许一个应用当中有多个线程并行执行。

在HotSpotJVM当中,每个线程都和操作系统当中的本地线程直接映射。

  • 当一个Java线程准备好执行之后,一个操作系统的本地线程也同时创建。

    Java线程执行终止之后,本地线程也就回收。

操作系统负责将线程安排调度到任何一个可用的CPU上。

一旦本地线程初始化成功,它就会调用Java线程的run方法。

JVM系统线程

在后台有许多线程运行。

这些线程并不包括调用public

static

args)的main线程以及所有这个main线程创建的线程。

这些主要的后台系统线程在HotSpot

JVM当中主要是这几个:

  1. 虚拟机线程:这种线程操作是需要JVM达到安全点才会出现。

    这种线程执行类型包括StopTheWorld的垃圾收集、线程栈收集、线程挂起、偏向锁撤销

  2. 周期任务线程:这种线程是时间周期事件的体现,一般用于周期性操作的调度执行

  3. GC线程:这种线程对在JVM当中不同种类的垃圾收集行为提供支持

  4. 编译线程:这种线程在运行的时候会将字节码编译成为本地代码

  5. 信号调度线程:这种线程接收到信号并发送给JVM,在内部通过调用适当方法进行处理

Stop

The

操作

核心解释(垃圾回收为例)

编程当中(尤其是JVM、OG等运行时环境),Stop-The-World特指:为保证内存操作一致性,暂时暂停应用程序中所有的用户线程(业务逻辑线程),以便垃圾回收器安全执行标记、清理等操作。

“暂停”对象:仅限当前进行线程内的应用线程(用户代码),而非整个程序的所有线程

实际情况:GC线程依旧在运行(JVM当中GC线程继续工作),仅用户代码暂停

JVM安全点

概述

JVM语境下,安全点指的是:

  • JVM可以安全的暂停所有Java线程,执行全局性操作(例如GC)的特定程序位置

它是HotSpot等主流虚拟机实现中的一种运行时协作机制,本质目的是在不破坏程序语义的前提下完成需要“Stop-The-World”的操作。

为什么需要安全点

Java程序运行过程当中:

  • 线程在不断执行字节码

  • JIT会将热点代码编译成为机器码保存

  • 栈帧当中保存着对象引用(寄存器当中也可能存储)

当发生GC时,JVM需要:

  1. 遍历所有线程栈

  2. 精确到所有对象引用(Root)

  3. 标记存活的对象

问题是:

👉如果线程在任意位置被强制暂停,JVM可能无法确定:

  1. 某个寄存器当中是否有对象引用

  2. 当前指令是否处于中间状态

  3. 栈结构是否稳定

所以,我们需要:

等待线程运行到一个引用关系清晰,栈状态稳定的位置停下来。

这个位置就是安全点

本质

从实现的角度讲:

安全点就是编译器在生成机器码时候插入的检查点

HotSpot在以下位置插入

safepoint

roll:

  • 方法调用处

  • 循环回边(while

    、for等正常循环当中位置指向循环头部的“边”)

  • 异常跳转点

  • 方法返回前

当JVM需要STW时:

  1. 设置一个全局标识

  2. 所有线程运行到最近的safe

    point

  3. 检查该标识

  4. 自行挂起

这种机制被称为协作式中断

什么时候触发安全点?

最常见触发场景就是GC

其他场景:

  • 偏向锁撤销

  • 类重新定义

  • 线程Dump

……

概念区分——安全点&安全区

安全点(Safe

Point)

  • 必须运行到某个“特定位置”才能停

  • 线程是运行状态

  • 需要主动检查

安全域(Safe

Region)

适用于:

  • 线程阻塞

  • 线程sleep

  • 线程wait

当线程进入这些状态时:

它告诉JVM:

当前不改变对象引用,可以安全使用GC

这段时间叫安全域

程序计数器(PC寄存器)

介绍

官方文档网址

https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

/>

JVM当中的程序计数寄存器(Program

Counter

Register)当中,Register命名源于CPU寄存器,寄存器存储指令相关的现场信息

CPU只有将数据装载到寄存器当中才能运行。

这里,并非是物理上的寄存器,而是PC计数器/指令计数器,或者称为程序钩子。

实际上,PC寄存器是对程序执行位置的抽象表示。

PC寄存器使用了很小的内存空间,几乎可以忽略不计。

(也是运行速度最快的存储区域)

JVM规范当中,每个线程都有自己的程序计数器,是线程私有的生命周期和线程的生命周期保持一致

任何时间一个线程都只有一个方法正在执行,这就是所谓的当前方法。

程序计数器或存储当前正在执行的Java方法的JVM指令地址;如果正在执行native方法(方法的实现并不在Java当中,而是在本地语言(通常是c/c++)当中实现),则是undefined(未定值,因为此时PC并不指向有效的字节码地址)

PC程序计数器是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器完成。

字节码解释器工作时通过计数器值的改变选取下一条需要执行的字节码指令。

它是唯一一个在Java虚拟机规范中没有规定任何OutofMemoryError情况的区域。

(不存在出现内存不足的可能性)

作用

PC寄存器用来存储指向下一条指令的地址,也就是即将执行的代码。

有执行引擎读取下一条指令,并执行该指令。

/>

EXAMPLE

查看字节码方法:https://blog.csdn.net/21aspnet/article/details/88351875

public

class

}

得到字节码:

Classfile

/F:/IDEAWorkSpaceSourceCode/JVMDemo/out/production/chapter04/com/atguigu/java/PCRegisterTest.class

Last

53b3ef104479ec9e9b7ce5319e5881d3

Compiled

com.atguigu.java.PCRegisterTest

minor

java/lang/Object."<init>":()V

=

java/lang/System.out:Ljava/io/PrintStream;

=

java/io/PrintStream.println:(I)V

=

com/atguigu/java/PCRegisterTest

=

Lcom/atguigu/java/PCRegisterTest;

#14

com/atguigu/java/PCRegisterTest

#33

com.atguigu.java.PCRegisterTest();

descriptor:

java/lang/Object."<init>":()V

return

Lcom/atguigu/java/PCRegisterTest;

public

java/lang/System.out:Ljava/io/PrintStream;

17:

java/io/PrintStream.println:(I)V

21:

java/lang/System.out:Ljava/io/PrintStream;

24:

java/io/PrintStream.println:(I)V

28:

"PCRegisterTest.java"

左边数字代表的是指令地址(指令偏移量),也是PC寄存器当中可能存储的值,然后执行引擎读取PC寄存器当中的值,执行对应的指令。

/>

常见面试题

使用PC寄存器存储字节码指令地址作用是什么?/为什么使用PC寄存器记录当前线程的执行地址?
  1. CPU需要不停切换各个线程,切换回某个个线程的时候我们需要知道接着从哪里开始执行

  2. JVM字节码解释器需要通过PC寄存器的值明确下一条执行什么字节码指令

/>

为什么PC寄存器设定为私有的?

由于CPU使用时间片轮转机制,在并发执行过程当中,任何一个确定的时刻,一个处理器内核只会运行一个线程的指令流(加载变量、计算、判断、循环、写入内存等多条指令构成的流)

这必然导致线程执行过程当中频繁的中断(挂起)与恢复(唤醒),即上下文切换

为保障线程在被挂起之后,下次能够从准确的位置恢复执行,JVM在内存当中为每个线程分配了私有的PC计数器、虚拟机栈。

PC计数器在各个线程之间互不干扰(被线程私有)。

当CPU切换回该线程时,依据PC计数器的值JVM知道下一步执行的代码,从而保障程序流程分毫不差。

CPU时间片

CPU分配给每个线程时间,每个线程被分配一个时间段,称为时间片。

宏观而言:我们可以同步打开多个应用程序,每个程序并行不悖,同时运行

微观而言:一般情况下,电脑上单核CPU/多核CPU,核心数量都是有限的,CPU的单个核心在任何一个特定纳秒级瞬间,只能处理一个线程的指令流。

为实现宏观上的并发,操作系统引入时间片轮转机制:将CPU执行时间分割为极短的时间片段(通常为毫秒级别),分配给不同的线程轮流执行

/>

本地方法&本地方法栈

本地方法

/>

  • 简单而言,一个本地方法就是Java声明的、由非Java代码实现、通过JNI(Java

    Native

    Interface)和JVM交互执行的方法,例如C/C++实现。

    C++当中也有类似机制,例如可以使用extern告知C++编译器调用C语言函数。

  • 定义一个本地方法(native

    method)时,并不提供实现体,因为其实现是非Java在外部实现的。

作用:

融合不同的编程语言为Java所用

EX:

注意:标识符native可以和其他java标识符连用(除abstract)

public

class

}

使用的原因

Java使用方便,但是有些层次任务使用java实现并不容易,或者对程序效率要求很高时就会存在一定问题。

用于和Java环境外交互

Java应用忧思需要和Java外的硬件进行交互(本地方法存在的主要原因)。

例如:

Java的一些应用需要和操作系统、外部硬件交换信息。

本地方法为Java提供了这样的机制:提供一个非常简洁的接口,无需了解Java应用之外的繁文缛节。

与操作系统交互

JVM支持着Java语言本身和运行时库,它是Java程序赖以生存的平台,它由一个解释器(解释字节码)和一些连接到本地代码的库组成。

然而不管怎样,它毕竟不是一个完整的系统,它经常依赖于一底层系统的支持。

这些底层系统常常是强大的操作系统。

通过使用本地方法,我们得以用Java实现了jre的与底层系统的交互,甚至JVM的一些部分就是用C写的。

还有,如果我们要使用一些Java语言本身没有提供封装的操作系统的特性时,我们也需要使用本地方法。

Sun's

Java(Sun的Java平台实现)

Sun的解释器使用的是c语言实现的,使得其能够像C一样和外部进行交互。

jre大部分使用的是Java实现的,也可以通过本地方法和外界交互。

EX:

类java.lang.Thread的setPriority()方法是用Java实现的,但是它实现调用的是该类里的本地方法setPriority0()。

这个本地方法是用C实现的,并被植入JVM内部在Windows

SetThreadPriority()

API。

这是一个本地方法的具体实现由JVM直接提供(JVM源码实现),更多的情况是本地方法由外部的动态链接库(external

dynamic

library)提供(开发者通过C/C++实现,编译成为.dll/.so文件,通过System.loadLibrary()加载),然后被JVM调用。

本地方法现状

使用的越来越少

除非是与硬件有关的应用,比如通过Java程序驱动打印机或者Java系统管理生产设备,在企业级应用中已经比较少见。

因为现在的异构领域间的通信很发达,比如可以使用Socket通信,也可以使用Web

Service等等,不多做介绍。

本地方法栈

Java虚拟机栈管理Java方法调用,本地方法栈用于管理本地方法调用。

注意:本地方法栈也是线程私有的

本地方法栈被允许实现成固定大小/可动态扩展的内存大小(内存溢出方面和虚拟机栈表现相同:StackOverflowError/OutOfMemoryError)

  • 如果线程请求分配的栈容量超过本地方法栈允许的最大容量,Java虚拟机将会抛出一个stackoverflowError

    异常。

  • 如果本地方法栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的本地方法栈,那么Java虚拟机将会抛出一个outofMemoryError异常。

具体做法:本地方法栈当中登记本地方法,执行引擎执行时加载本地方法。

/>

Attetion:

  1. 当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界。

    它和虚拟机拥有同样的权限。

    1. 本地方法可以通过本地方法接口来访问虚拟机内部的运行时数据区

    2. 它甚至可以直接使用本地处理器中的寄存器

    3. 直接从本地内存的堆中分配任意数量的内存

  2. 并不是所有的JVM都支持本地方法。

    因为Java虚拟机规范并没有明确要求本地方法栈的使用语言、具体实现方式、数据结构等。

    如果JVM产品不打算支持native方法,也可以无需实现本地方法栈。

  3. 在Hotspot

    JVM中,直接将本地方法栈和虚拟机栈合二为一。



SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback