JVM 虚拟机 ----> Java 内存模型(JMM)
文章目录
- Java 内存模型(JMM)
- 一、运行时数据区域划分
- 二、程序计数器(Program Counter Register)
- 计数器的作用
- 三、Java 虚拟机栈(VM Stack)
- 四、本地方法栈(Native Method Stack)
- 五、堆(Heap)
- 1、概述
- 2、新生代、老年代
- 3、创建对象的内存分配
- 六、元空间(Meta Space)
- 1、作用
- 2、发展历程
- (1)JDK 1.6
- (2)JDK 1.7
- (3)JDK 1.8
- 七、字符串常量池
- 1、字符串的两种创建方式
- 2、intern() 方法
- 3、String 的拼接
Java 内存模型(JMM)
JMM ,全称 Java Memory Model ,中文释义 Java 内存模型
一、运行时数据区域划分
- JVM 虚拟机在执行 Java 程序过程中会把它管理的内存划分成若干个不同的数据区域‘
JDK 1.8
之前分为:线程共享(Heap
堆区、Method Area
方法区)、线程私有(虚拟机栈、本地方法栈、程序计数器)JDK 1.8
以后分为:线程共享(Heap
堆区、MetaSpace
元空间)、线程私有(虚拟机栈、本地方法栈、程序计数器)
二、程序计数器(Program Counter Register)
程序计数器是一块较小的内存空间,是当前线程所执行的字节码的行号指示器
- 字节码解释器在解释执行字节码文件工作时,每当需要执行一条字节码指令时,就通过改变程序计数器的值来完成。程序中的分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。
- 程序执行过程中,会不断的切换当前执行线程,切换后,为了能让当前线程恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,并且各线程之间计数器互不影响,独立存储。
计数器的作用
- 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理
- 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候,能够知道当前线程的运行位置
- 程序计数器是唯一一个不会出现 OutOfMemoryError的内存区域,它随着线程的创建而创建,随着线程的结束而死亡
三、Java 虚拟机栈(VM Stack)
与程序计数器一样,VM Stack
虚拟机栈也是线程私有的,它的生命周期和线程相同,用于描述 Java 方法执行时的内存模型,每次方法调用的数据都是通过栈传递的。
JMM
内存区域可以粗略的区分为堆内存(Heap
)和栈内存 (Stack
)。其中栈就是VM Stack
虚拟机栈,或者说是虚拟机栈中局部变量表部分。
局部变量表主要存放了编译期可知的各种基本数据类型变量值(boolean
、byte
、char
、short
、int
、float
、long
、double
)、对象引用(reference
类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)
Java
虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。
每一次方法调用都会有一个对应的栈帧被压入 VM Stack
虚拟机栈,每一个方法调用结束后,代表该方法的栈帧会从VM Stack
虚拟机栈中弹出。
在活动线程中, 只有位于栈顶的帧才是有效的, 称为当前活动栈帧,代表正在执行的当前方法。
在JVM
执行引擎运行时, 所有指令都只能针对当前活动栈帧进行操作。虚拟机栈通过 pop
和 push
的方式,对每个方法对应的活动栈帧进行运算处理,方法正常执行结束,肯定会跳转到另一个栈帧上。
-
Java
方法有两种返回方式,不管哪种返回方式都会导致当前活动栈帧被弹出 -
return
语句- 抛出异常
Java
虚拟机栈会出现两种错误:StackOverFlowError 和OutOfMemoryError
- StackOverFlowError:当线程请求栈的深度超过
JVM
虚拟机栈的最大深度的时候,就抛出StackOverFlowError
错误。 - OutOfMemoryError:
JVM
的内存大小可以动态扩展, 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError
异
四、本地方法栈(Native Method Stack)
本地方法栈用于虚拟机调用的 Native
方法
native
关键字修饰的本地方法被执行的时候,在本地方法栈中也会创建一个栈帧,用于存放该native
本地方法的局部变量表、操作数栈、动态链接、方法出口信息。方法执行完毕后,相应的栈帧也会出栈并释放内存空间。也会出现 StackOverFlowError
和 OutOfMemoryError
两种错误
五、堆(Heap)
1、概述
Heap
堆区,用于存放对象实例和数组的内存区域
Heap
堆是JVM
所管理的内存中最大的一块区域,被所有线程共享的一块内存区域。堆区中存放对象实例,“几乎”所有的对象实例以及数组都在这里分配内存
Java
世界中“几乎”所有的对象都在堆中分配,但是,随着 JIT
编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。
从JDK 1.7
开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被外面使用(也就是未逃逸出去),那么对象可以直接在栈上分配内存
2、新生代、老年代
Heap 堆是 **垃圾收集器 GC(Garbage Collected)**管理的主要区域,因此堆区也被称为 GC堆(Garbage Collected Heap)
从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 JVM 中的堆区往往进行分代划分,例如:新生代 和 老年代。目的是更好地回收内存,或者更快地分配内存
Heap 堆区中的新生代、老年代的空间分配比例,可以通过java -XX:+PrintFlagsFinal -version
命令查看
上述输出结果结果分析
InitialSurvivorRatio = 8
新生代Young(Eden/Survivor)
空间的初始比例 = 8:代表Eden
占新生代空间的80%
;
uintx NewRatio = 2
老年代Old
/ 新生代 Young
的空间比例 = 2 : 代表老年代Old
是新生代Young
的2倍
因为新生代是由 Eden + s0 + s1 组成的,所以按照上述默认比例,如果
Eden` 区内存大小是 40M,那么两个 Survivor 区就是 5M,整个新生代区就是 50M,然后可以算出 Old 区内存大小是 100M,堆区总大小就是 150M
3、创建对象的内存分配
- 创建一个新对象,在堆中分配内存
- 大部分情况下,对象会在 Eden 区生成,当 Eden 区装满时,会触发 Young Garbage Collection,即 YGC 垃圾回收时,在 Eden 区实现清除策略,没有被引用的对象直接被回收
- 依然存活的对象会被移送到 Survivor 区
- Survivor 区分为 s0 和 s1 两块内存区域,每次 YGC 的时候,将存活的对象复制到未使用的 Survivor 空间(s0 或 s1),然后清空正在使用的空间,交换 s0 和 s1 的使用状态,每次交换时, 对象的Age+1
- 如果 YGC 要移送的对象大于 Survivor 区容量的上限,则直接移交给老年代
- 一个对象也不可能永远呆在新生代,在
JVM
中 一个对象从新生代晋升到老年代的阈值默认值是15
,可以在Survivor
区交换 14 次之后,晋升至老年代
堆区最容易出现的就是 OutOfMemoryError
错误,这种错误的表现形式会有以下两种:
OutOfMemoryError: GC Overhead Limit Exceeded
: 当JVM
花太多时间执行垃圾回收,并且只能回收很少的堆空间时,就会发生此错误。OutOfMemoryError: Java heap space
**:**假如在创建新的对象时, 堆内存中的空间不足以存放新创建的对象, 就会引发此错误。
此种情况,与配置的最大堆内存有关,且受制于物理内存大小。
六、元空间(Meta Space)
1、作用
用于存放 类信息、常量、静态变量、JIT 即时编译器编译后的机器代码等数据
例如:java.lang.Object
类的元信息、Integer.MAX_VALUE
常量等
2、发展历程
(1)JDK 1.6
HotSpot JVM
使用Method Area
方法区存储,也叫永久代(Permanent Generation)。
- 方法区和“永久代(
Permanent Generation
)”的区别:方法区是JVM
的规范,而永久代(Permanent Generation
)是JVM
规范的一种实现,并且只有HotSpot JVM
才有永久代“Permanent Generation
”,而对于其他类型的虚拟机,如 JRockit(Oracle)、J9(IBM) 并没有; - 方法区是一片连续的堆空间,当
JVM
加载的类信息容量超过了最大可分配空间,虚拟机会抛出OutOfMemoryError:PermGenspace
的Error
。 - 永久代的GC是和老年代(
old generation
)捆绑在一起的,无论谁满了,都会触发永久代和老年代的垃圾收集。 - 可以通过
-XX:PermSize=N
设置 方法区 (永久代) 初始空间,-XX:MaxPermSize=N
设置方法区 (永久代) 最大空间,超过这个值将会抛出错误:java.lang.OutOfMemoryError: PermGen
(2)JDK 1.7
将字符串常量池、静态变量转移到了堆区。
(3)JDK 1.8
正式移除永久代,采用 Meta Space 元空间替代
元空间的本质和永久代类似,都是对JVM
规范中方法区的一种具体实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过运行参数来指定元空间的大小。
Java 8
中 PermGen
永久代为什么被移出 HotSpot JVM
?
- 由于
PermGen
内存经常会溢出,容易抛出java.lang.OutOfMemoryError: PermGen
错误; - 移除
PermGen
可以促进HotSpot JVM
与JRockit VM
的融合,因为JRockit
没有永久代
**示例1:**不断的生成新的字符串,快速的消耗内存。通过 JDK 1.6
、JDK 1.7
和 JDK 1.8
分别运行。
public class TestOOM {static String base = "ApeSource";public static void main(String[] args) {List<String> list = new ArrayList<String>();for (int i=0;i< Integer.MAX_VALUE;i++){String str = base + base;base = str;list.add(str.intern());}}
}
上述运行结果可以看出,相同的代码,在JDK 1.6
会出现“PermGen Space
”的永久代内存溢出,而在 JDK 1.7
和 JDK 1.8
中,会出现"Java heap space
"堆内存溢出,并且 JDK 1.8
中 PermSize
和 MaxPermGen
参数已经无效。因此,在 JDK 1.7
和 JDK 1.8
中,已经将字符串常量由永久代转移到堆中,并且 JDK 1.8
中已经完全移除了永久代,采用元空间来代替。
**示例2:**在 JDK 8
下重新运行一下运行测试代码TestOOM
,指定 MetaSpaceSize
和 MaxMetaSpaceSize
的大小,输出结果如下:
-XX:MetaspaceSize
**参数:主要控制Meta Space GC
发生的初始阈值,也就是最小阈值,当使用的Meta Space 空间到达
MetaspaceSize`**的时候,就会触发Metaspace的GC。- -
XX:MaxMetaspaceSize参数:最大空间,默认是没有限制的。在
jvm启动的时候,并不会分配MaxMetaspaceSize
这么大的一块内存出来,metaspace
是可以一直扩容的,直到到达MaxMetaspaceSize
七、字符串常量池
1、字符串的两种创建方式
- 第一种方式是在常量池中获取字符串对象;
- 第二种方式是直接在堆内存空间创建一个新的字符串对象
// 先检查字符串常量池中有没有"abcd",如果字符串常量池中没有,则创建一个,然后 str1 指向字符串常量池中的对象,如果有,则直接将 str1 指向"abcd"
String str1 = "apesource";
String str2 = new String("apesource"); //堆中创建一个新的对象
String str3 = new String("apesource"); //堆中创建一个新的对象System.out.println(str1==str2); //false
System.out.println(str2==str3); //false
2、intern() 方法
- 检查指定字符串在常量池中是否存在?如果存在,则返回地址,如果不存在,则在常量池中创建
String s1 = new String("Apesource");
String s2 = s1.intern(); // 查看字符串常量池中是否存在"Apesource",如果存在则返回地址,如果不存在,则在常量池中创建
String s3 = "Apesource"; // 使用常量池中的已有字符串常量"Apesource"System.out.println(s2 == s3); // true,地址相同
3、String 的拼接
String str1 = "str";
String str2 = "ing";String str3 = "str" + "ing"; // 常量池中的新字符串对象
String str4 = str1 + str2; // 在堆中创建的新字符串对象
String str5 = "string"; // 常量池中的已有字符串对象System.out.println(str3 == str4); //false
System.out.println(str3 == str5); //true
System.out.println(str4 == str5); //false
String s1 = new String("abc");
这句代码创建了几个字符串对象?
创建 1
或 2
个字符串。如果常量池中已存在字符串常量“abc
”,则只会在堆空间创建一个字符串常量“abc
”
如果常量池中没有字符串常量“abc
”,那么它将首先在池中创建,然后在堆空间中创建,因此将创建总共2 个字符串对象
相关文章:
JVM 虚拟机 ----> Java 内存模型(JMM)
文章目录 Java 内存模型(JMM)一、运行时数据区域划分二、程序计数器(Program Counter Register)计数器的作用 三、Java 虚拟机栈(VM Stack)四、本地方法栈(Native Method Stack)五、…...
指针-字符串替换
任务描述 从标准输入读入数据,每行中最多包含一个字符串 “_xy_”,且除了字符串“_xy_”外,输入数据中不包括下划线字符,请将输入行中的 “_xy_” 替换为 “_ab_”, 在标准输出上输出替换后的结果;若没有进行过满足条…...
docker 网络(单机环境)
文章目录 深入理解 Namespace什么是NamespaceNamespace当中的 Network Namespace Libcontainerdocker 网络基础创建两个命名空间创建网络接口 veth pair命名空间添加 veth 接口为 veth 接口分配 IP启动 veth 接口相互 ping bridge 网络搭建网络环境查看docker0 网桥创建网桥 br…...
14、二叉树的morris遍历等
统计热词 有一个包含100亿个URL的大文件,假设每个URL占用64B,请找出其中所有重复的URL 【补充】 某搜索公司一天的用户搜索词汇是海量的(百亿数据量),请设计一种求出每天热门Top100 词汇的可行办法 多个小文件的大根堆,然后把每…...
BeanFactory与ApplicationContext
BeanFactory与ApplicationContext的区别 使用Alt Ctrl U查看java类图 什么是BeanFactory接口 他是ApplicationContext的父接口他才是Spring 的核心容器,主要的ApplicationContext功能的实现都间接通过BeanFactory接口来实现 在ApplicationContext类中方法的实现是…...
【计算机网络】 粘包问题
文章目录 为什么会产生粘包问题?解决办法先发包大小再发包内容代码示例 为什么会产生粘包问题? tcp是数据流传输,是一种没有边界的,可以合并的传输数据方式。合并就要能拆开,拆不开就是粘包。 解决办法 设置标志位&a…...
valgrind massif 详解(内存分配释放分析)
参考 https://valgrind.org/docs/manual/ms-manual.html 使用格式 valgrind --toolmassif [--massif-opts] prog [prog-args]目的 记录每一次的malloc, free; 概念: malloc申请内存, 实际分配内存(字节对齐, 分配器的记录头, 等等原因) 对内存进行分析, 优化, 以达到资源…...
使用命令行创建一个vue项目卡住不动如何解决
问题 在使用命令去创建一个vue项目, 出现下面卡住不动的一个状态。 解决方案一 首先先ctrlc停止进入创建好的项目文件手动输入npm install 、npm run dev如果npm run dev 的时候 出现 ‘vite’ 相关的错误查看node版本是否是最新的稳定版本node -v查看安装源是否…...
七天学会C语言-第一天(C语言基本语句)
一、固定格式 这个是C程序的基本框架,需要记住!!! #include<stdio.h>int main(){return 0; }二、printf 语句 简单输出一句C程序: #include<stdio.h> int main(){printf("大家好,&quo…...
vue项目部署,出现两个ip的原因
我宁愿靠自己的力量打开我的前途,而不愿求有力者的垂青。——雨果 tags: 篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue项目部署,出现两个ip的原因相关的知识,希望对你有一定的参考价值。 参考技术A 在部署v…...
无涯教程-JavaScript - ASIN函数
描述 ASIN函数返回给定数字的反正弦或反正弦,并返回以弧度表示的Angular,介于-π/2和π/2之间。 语法 ASIN (number)争论 Argument描述Required/OptionalNumberThe sine of the angle you want and must be from -1 to 1.Required Notes 如果您希望ASIN函数返回的Angular以…...
MYSQL的SQL优化
insert语句 开启事务 手动控制事务 start transaction; insert into tb_test values(1,Tom),(2,Cat),(3,Jerry); insert into tb_test values(4,Tom),(5,Cat),(6,Jerry); insert into tb_test values(7,Tom),(8,Cat),(9,Jerry); commit; 内存插入 load命令中用 fields te…...
lintcode 553 · 炸弹袭击【中等 数组+bfs+模拟】
题目 https://www.lintcode.com/problem/553 给定一个二维矩阵, 每一个格子可能是一堵墙 W,或者 一个敌人 E 或者空 0 (数字 0), 返回你可以用一个炸弹杀死的最大敌人数. 炸弹会杀死所有在同一行和同一列没有墙阻隔的敌人。 由于墙比较坚固,所以墙不会被摧毁.你只…...
第一章 计算机系统概述 八、虚拟机
目录 一、传统虚拟机的结构 二、两类虚拟机管理程序 (1)定义: (2)区别:(考点) 一、传统虚拟机的结构 二、两类虚拟机管理程序 (1)定义: &…...
桶装水送水多水站送水员公众号h5开发
桶装水送水多水站送水员公众号h5开发 界面简洁易懂用户容易接受。 独家一户一码全家都能订水。 多个水站运营可按距离选择绑定。 三种支付方式水票、微信、到付。 强大员工系统老板坐享其成。 自由跑跑模式可招兼职送水员接单。 一户一码、全家享用 一户一码,精准…...
【JavaEE】多线程(二)
多线程(二) 文章目录 多线程(二)第一个多线程程序观察线程sleep创建线程继承Thread类,重写run方法实现Runnable, 重写run继承Thread,重写run实现Runnable,重写run基于lambda表达式 T…...
OkHttp 根据服务器返回的的过期时间设置缓存
据返回的缓存时间来缓存响应,可以通过使用OkHttp的CacheControl和ResponseCacheInterceptor来实现。以下是一个示例代码: // 创建缓存目录和缓存对象 File cacheDirectory new File(context.getCacheDir(), "http-cache"); int cacheSize 1…...
智能远程监考方案助力企业考试化繁为简
在音视频数字化之旅中,轻装上阵。 近年来,在数字化浪潮之下,远程考试频繁成为各领域热词,各企业也纷纷改革求新,将原本的企业内部考试转移到线上,从而获取更低廉的组考成本,更高的管理效率&…...
基于matlab实现的额 BP神经网络电力系统短期负荷预测未来(对比+误差)完整程序分享
基于matlab实现的额 BP神经网络电力系统短期负荷预测 完整程序: clear; clc; %%输入矢量P(15*10) P[0.2452 0.1466 0.1314 0.2243 0.5523 0.6642 0.7105 0.6981 0.6821 0.6945 0.7549 0.8215 0.2415 0.3027 0; 0.2217 0.1581 0.1408 0.23…...
WPF的_Expander控件
WPF Expander 是 WPF(Windows Presentation Foundation)框架中的一个控件,用于实现可以展开和折叠内容的可折叠面板。 Expander 控件通常由一个展开/折叠的标题(Header)和一个显示/隐藏的内容部分(Content…...
【MT7628AN】IOT | MT7628AN OpenWRT开发与学习
IOT | MT7628AN OpenWRT开发与学习 时间:2023-06-21 文章目录 `IOT` | `MT7628AN` `OpenWRT`[开发与学习](https://blog.csdn.net/I_feige/article/details/132911634?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22132911634…...
基于Matlab实现自动泊车(垂直泊车)
自动泊车是一项非常有趣和实用的技术,它可以让车辆在没有人为干预的情况下自动停放在合适的位置上。在这篇文章中,我们将介绍如何使用Matlab实现自动泊车。 首先,我们需要了解自动泊车的基本原理。自动泊车系统通常包括车辆、传感器和控制算…...
笔试面试相关记录(4)
(1)实现防火墙的主流技术有哪些? 实施防火墙主要采用哪些技术 - 服务器 - 亿速云 (yisu.com) (2) char arr[][2] {a, b, c, d}; printf("%d", *(arr1)); 输出的是谁的地址?字符c 测试代码如下…...
unity UDP 通信
客户端 接收端 : using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using UnityEngine; using UnityEngine.UI;public cla…...
一篇解决JavaScript
华子目录 JavaScript介绍JavaScript的组成JavaScript书写位置内部外部 js注释js输入(prompt)js输出js变量js基本数据类型number(数值类型)string(字符串)Boolean(布尔类型)undefined…...
Unity UGUI(一)基础组件
文章目录 1.Text:文本框2.Image:精灵图3.RawImage:生图4.Button:按钮5.InputField:输入框6.Tooggle:选择框7.Slider:滑动条8.Dropdown:下拉菜单9.Scrollbar:滚动条10.Scr…...
【微服务】六. Nacos配置管理
6.1 Nacos实现配置管理 配置更改热更新 在nacos左侧新建配置管理 Data ID:就是配置文件名称 一般命名规则:服务名称-环境名称.yaml 配置内容填写:需要热更新需求的配置 配置文件的id:[服务名称]-[profile].[后缀名] 分组&#…...
【华为云云耀云服务器L实例评测|云原生】自定制轻量化表单Docker快速部署云耀云服务器
🤵♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…...
无涯教程-JavaScript - ACOTH函数
描述 ACOTH函数返回数字的反双曲余切。 语法 ACOTH (number)争论 Argument描述Required/OptionalNumberThe absolute value of Number must be greater than 1. i.e., Number must be must be less than -1 or greater than 1.Required Notes 用于计算双曲反余切的方程为-…...
Qt QTreeWidge解决setItemWidget后,导致复选框失效
一、问题: QTreeWidget某一项加上itemWidget后,导致复选框失效问题 二、解决方法 将要加上的widget控件加到该项的后续的列,即控件跟复选框不同一列 三、具体代码 QTreeWidget* treeW new QTreeWidget; treeW->setColumnCount(2); /…...
免费门户网站模板/搜狗seo软件
PCB线路板布线有哪些常用规则?文/中信华PCB在我们的日常生活中,我们所接触到的每一种电子设备当中几乎都会出现印刷电路板,如果在某样设备中有电子零件,那么它们也都是镶在大小各异的PCB上。要使电子电路获得最佳性能,…...
蚌埠北京网站建设/关键词密度
欢迎关注”生信修炼手册”!字典是使用最为广泛的数据结构了,从结构来看,其内容就是键值对,键称为key, 值称为value, 类似词典中通过前面的索引来快速查找后面的页面,通过key可以快速定位对应的值。字典,是python中对这…...
笔记本做网站外网访问/360竞价推广客服电话
苏生不惑第220 篇原创文章,将本公众号设为星标,第一时间看最新文章。之前我发过好几篇关于Python的文章:七夕又来了,给女朋友做个动态二维码一键下载公众号所有文章,导出文件支持PDF,HTML,Markd…...
濮阳网站建设在哪做/临沂百度联系方式
Hive的简单应用 参考一下此文章 Hive详细介绍及简单应用...
wordpress怎么自动生成内链/360站长工具seo
LinkedList实现队列简单描述:使用java.util.Queue接口,其底层关联到一个LinkedList(双端队列)实例。由于只暴露部分基于队列实现的接口,所以可以提供安全的队列实现。 LinkedList实现队列代码: package junit;import j…...
面试网站建设问题/电话营销销售系统
“云计算”这个词在今年颇为流行,以至于我终于不能再继续厚着脸皮当作没看到了。最初,我以为云计算就是一堆客户端计算机紧密的团结在一起,为一个共同的伟大的问题而献出自己的业余时间。后来某男告诉我,那叫网格计算,…...