几百万数据放入内存会不会把系统撑爆?

几百万数据放入内存不会把系统撑爆吗? 在公司有一个需求是要核对一批数据,之前的做法是直接用SQL各种复杂操作给怼出来的,不仅时间慢,而且后期也不好维护,就算原作者来了过一个月估计也忘了SQL什么意思了,于是有一次我就想着问一下之前做这个需求的人为什么不将这些数据查出来后在内存里面做筛选呢?直接说了你不怕把内存给撑爆吗?此核算服务器是单独的服务器,配置是四核八G的,配置堆的大小是4G。本着怀疑的精神,就想要弄清楚几百万条数据真的放入内存... 阅读详情

作者:不学无数的程序员

https://my.oschina.net/u/4030990/blog/3145683

在公司有一个需求是要核对一批数据,之前的做法是直接用SQL各种复杂操作给怼出来的,不仅时间慢,而且后期也不好维护,就算原作者来了过一个月估计也忘了SQL什么意思了,于是有一次我就想着问一下之前做这个需求的人为什么不将这些数据查出来后在内存里面做筛选呢?直接说了你不怕把内存给撑爆吗?此核算服务器是单独的服务器,配置是四核八G的,配置堆的大小是4G。本着怀疑的精神,就想要弄清楚几百万条数据真的放入内存的话会占用多少内存呢?

计算机的存储单位

计算机的存储单位常用的有 bit、 Byte、 KB、 MB、 GB、 TB后面还有但是我们基本上用不上就不说了,我们经常将 bit称之为比特或者位、将 Byte简称为 B或者字节,将 KB简称为 K,将 MB称之为M或者兆,将 GB简称为 G。那么他们的换算单位是怎样的呢?

换算关系

首先我们得知道在计算机中所有数据都是由 01来组成的,那么存储 01这些二进制数据是由什么存放呢?就是由 bit存放的,一个 bit存放一位二进制数字。所以 bit是计算机最小的单位。

大部分计算机目前都是使用8位的块,就是我们上面称之为的字节 Byte,来作为计算机容量的基本单位。所以我们一般称一个字符或者一个数字都是称之为占用了多少字节。

了解了上面关于位和字节的关系后,我们可以看一下其他的单位换算关系

1B(Byte 字节) = 8bit(位)
1KB = 1024B
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB

Java中对象占用多少内存

在了解了上面的换算关系后,我们来了解一下新建一个Java对象需要多少内存。

Java基本类型

我们知道Java类型分为基本类型和引用类型,八大基本类型有 int、short、long、byte、float、double、boolean、char

数据类型占用内存(单位为Byte)
boolean1
byte1
short2
char2
int4
float4
long8
double8

至于为什么Java中的char无论是中英文数字都占用两个字节,是因为Java中使用Unicode字符,所有的字符均以两个字节存储。

Java引用类型

在一个对象中除了有基本数据类型以外,我们也会有一些引用类型,引用类型的对象比较特殊,因为这些对象真正存储在虚拟机中的堆内存中,对象中只是存储了一个引用而已,如果是引用类型那么就会存储一个指向该引用的指针。指针默认情况下是占用4字节,是因为开启了指针压缩,如果没有开的话,那么一个引用就占用8个字节。

对象在内存中的布局

在HotSpot虚拟机中,对象在内存中存储的布局可以分为三个区域:对象头(Header)、实例数据(Instance Data)、对齐填充(Padding)。

对象头

在对象头中存储了两部分数据

  • 运行时数据:存储了对象自身运行时的数据,例如哈希码、GC分代的年龄、锁状态标志、线程持有的锁、偏向线程ID等等。这部分数据在32位和64位的虚拟机中分别为32bit和64bit

  • 类型指针:对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。如果对象是一个Java数组的话,那么对象头中还必须有一块用于记录数组长度的数据(占用4个字节)。所以这是一个指针,默认JVM对指针进行了压缩,用4个字节存储。

我们以虚拟机为64位的机器为例,那么对象头占用的内存是8(运行时数据)+4(类型指针)=12Byte。如果是数组的话那么就是16Byte

实例数据

实例数据中也拥有两部分数据,一部分是基本类型数据,一部分是引用指针。这两部分数据我们在上面已经讲了。具体占用多少内存我们需要结合具体的对象继续分析,下面我们会有具体的分析。

从父类中继承下来的变量也是需要进行计算的

对齐填充

对齐填充并不是必然存在的,也没有特别的含义。它仅仅起着占位符的作用。由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是对象的大小必须是8字节的整数倍。而如果对象头加上实例数据不是8的整数倍的话那么就会通过对其填充进行补全。

实战演练

我们在上面分析一大堆,那么是不是就如我们分析的一样,新建一个对象在内存中的分配大小就是如此呢?我们可以新建一个对象。

class Animal{
    private int age;
}

那么怎么知道这个对象在内存中占用多少内存呢?JDK提供了一个工具 jol-core可以给我们分析出来一个对象在内存中占用的内存大小。直接在项目中引入包即可。

--Gradle
compile 'org.openjdk.jol:jol-core:0.9'
--Maven
<dependency>
    <groupid>org.openjdk.jol</groupid>
    <artifactid>jol-core</artifactid>
    <version>0.9</version>
</dependency>

然后我们在main函数中调用如下

public class AboutObjectMemory {
    public static void main(String[] args) {
        System.out.print(ClassLayout.parseClass(Animal.class).toPrintable());
    }
}

就可以查看到输出的内容了,可以看到输出结果占用的内存是16字节,和我们分析的一样。

aboutjava.other.Animal object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0    12        (object header)                           N/A
     12     4    int Animal.age                                N/A
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
String占用多少内存

String字符串在Java中是个特殊的存在,比如一个字符串 "abcdefg"这样一个字符串占用多少字节呢?相信会有人回答说是7个字节或者是14个字节,这两个答案都是不准确的,我们先看一下String类在内存中占用的内存是多少。我们先自己进行分析一下。在String类中有两个属性,其中对象头固定了是12字节,int是4字节,char[]数组其实在这里相当于引用对象存的,所以存的是地址,因此占用4个字节,所以大小为 对象头12Byte+实例数据8Byte+填充数据4Byte=24Byte这里的对象头和实例数据加起来不是8的倍数,所以需要填充数据进行填充。

    private final char value[];
    private int hash; // Default to 0

那么我们分析的到底对不对呢,我们还是用上面的工具进行分析一下。可以看到我们算出的结果和我们分析的结果是一致的。

java.lang.String object internals:
 OFFSET  SIZE     TYPE DESCRIPTION                               VALUE
      0    12          (object header)                           N/A
     12     4   char[] String.value                              N/A
     16     4      int String.hash                               N/A
     20     4          (loss due to the next object alignment)
Instance size: 24 bytes

那么一个空字符串占用多少内存呢?我们刚才得到的是一个String对象占用了24字节,其实char[]数组还是会占用内存的,我们在上面讲对象头的时候说过,数组对象也是一个实例对象,它的对象头比一般的对象多出来4字节,用来描述此数组的长度,所以char[]数组的对象头长度为16字节,由于此时是空字符串,所以实例数据长度为0。因此一个空char[]数组占用内存大小为 对象头16Byte+实例数据0Byte=16Byte。一个空字符串占用内存为 String对象+char[]数组对象=40Byte

那么我们上面举的例子 abcdefg占用多少内存呢?其中String对象占用的内存是不会变了,变化的是char[]数组中的内容,这里我们需要知道字符串是存放于char[]数组中的,而一个byte占用2个字节,所以 abcdefg的char[]数组大小为 对象头16Byte+实例数据14Byte+对齐填充2Byte=32Byte。那么 abcdefg 占用内存大小就是 String对象+char[]数组对象=56Byte

用List存储对象

那么我们在内存中放入二千万个这个对象的话,需要占用多少内存呢?根据上面的知识我们能大概估算一下。我们定义一个List数组用于存放此对象,不让其回收。

List<animal> animals = new ArrayList<>(20000000);
for (int i = 0; i < 20000000; i++) {
    Animal animal = new Animal();
    animals.add(animal);
}

注意这里我是直接将集合的大小初始化为了二千万的大小,所以程序在正常启动的时候占用内存是100+MB,正常程序启动仅仅占用30+MB的,所以多出来的60+MB正好是我们初始化的数组的大小。至于为什么要初始化大小的原因就是为了消除集合在扩容时对我们观察结果的影响

这里我贴一张,集合未初始化大小和初始化大小内存占用对比图,大家可以看到是有内存上的差异,在ArrayList数组中用于存放数据的是 transientObject[]elementData;Object数组,所以它里面存放的是指向对象的指针,一个指针占用4个字节,所以就有两千万个指针,那么就是76M。我们可以看到差异图和我们预想的一样。

上面我们已经算出来了一个 Animal对象占用16个字节,所以两千万个占用大概是305MB,和集合加起来就是将近380MB的空间大小,接下来我们就启动程序来看一下我们结果是不是对的呢,接下来我用的 jconsole工具查看内存占用情况。

我们可以看到和我们预算的结果是相吻合的。

那么以后如果有大量的对象需要从数据库中查找出来放入内存的话,那么如果是使用对象来接的话,那么我们就应该尽量减少对象中的字段,因为即使你不赋值,其实他也是占用着内存的,我们接下来再举个例子看一下对个属性值的话占用内存是不是又高了。我们将 Animal对象改造如下

class Animal{
    private int age;
    private int age1;
    private int age2;
    private int age3;
    private int age4;
}

此时我们能够计算得到一个 Animal对象占用的内存大小是(对象头12Byte+实例数据20Byte=32Byte)此时32由于是8的倍数所以无需进行填充补齐。那么此时如果还是二千万条数据的话,此对象占用内存应该是610MB,加上刚才集合中指针的数据76MB,那么加起来将近占用686MB,那么预期结果是否和我们的一样呢,我们重新启动程序观察,可以看到下图。可以看到和我们分析的数据是差不多的。

用Map存储对象

用Map存储对象计算内存大小有些麻烦了,众所周知Map的结构是如下图所示。

它是一个数组加链表(或者红黑树)的结构,而数组中存放的数据是Node对象。

static class Node<k,v> implements Map.Entry<k,v> {
        final int hash;
        final K key;
        V value;
        Node<k,v> next;
}

我们举例定义下面一个Map对象

Map<animal,animal> map

此时我们可以自己计算一下一个Node对象需要的内存大小 对象头12Byte+实例数据16Byte+对其填充4Byte=32Byte,当然这里的key和value的值还需要另算,因为Node对象此时存放的仅仅是他们的引用而已。一个Animal对象所占用内存大小我们上面也说了是16Byte,所以这里一个Node对象占用的大小为32Byte+16Byte+16Byte=64Byte。

下面我们用实际例子来验证下我们的猜想

Map<animal,animal> map = new HashMap<>(20000000);
for (int i = 0; i < 20000000; i++) {
    map.put(new Animal(),new Animal());
}

上面的例子在一个Map对象中存放二千万条数据,计算大概在内存中占用多少内存。

  • 数组占用内存大小:我们先来计算一下数组占了多少,这里有个小知识点,在HashMap中初始化大小是按照2的倍数来的,比如你定义了大小为60,那么系统会给你初始化大小为64。所以我们定义为二千万,系统其实是会给我们初始化为33554432,所以此时仅仅HashMap中数组就占用了将近132MB

  • 数据占用内存大小:我们上面计算了一个Node节点占用了64Byte,那么两千万条数据就占用了1280MB

两个占用内存大小相加我们可以知道大概系统中占用了1.4G内存的大小。那么事实是否是我们想象的呢?我们运行程序可以看到内存大小如图所示。可以看到结果确实和我们猜想的一样。

总结

回归到上面所说的需求,几百万数据放到内存中会把内存撑爆吗?这时候你可以通过自己的计算得到。最终我们那个需求经过我算出来其实占用内存量几百兆,对于4个G的堆内存来说其实远远还没达到撑爆的地步。所以有时候我们对任何东西都要存在怀疑的态度。大家可以到GitHub中下载代码自己在本地跑一下监测一下,并且可以自己定义几个对象然后计算看是不是和图中的内存大小一致。这样才能记忆更深刻。送给大家一句话从来如此,便对吗?。其实我写的文章里面也留了一个小坑,大家可以试着找找,是在对集合进行初始化计算那一块。

项目源码:https://github.com/modouxiansheng/Doraemon

推荐阅读:

分享一套SpringBoot开发博客系统源码,以及完整开发文档!速度保存!

Github上最值得学习的100个Java开源项目,涵盖各种技术栈!

2020年最新的常问企业面试题大全以及答案

100万条记录的数据加载 用SQL Loder进行百万条数据加载的方法及优化  1、生成一个百万级数据文件  方法:找一找大小合适的表,进行笛卡尔积运算。 SQL> select count(*) from dba_objects; 15905 1 row selected. 将这个1.5W记录的表,与一个100条记录的表做笛卡尔积,就能生成150万记录了。 select a.o 阅读详情

相关推荐

在数据量大(超过10万)的情况下

在数据量大(超过10万)的情况下

java 如何循环执行一个对象_一个 Java 对象到底有多大?

阅读本文大概需要 2.8 分钟。出处:http://u6.gg/swLPg编写 Java 代码的时候,大多数情况下,我们很少关注一个 Java 对象究竟有多大(占据多少内存),更多的是关注业务与逻辑。但是殊不知,在我们不经意间,大量的内存被无形地浪费了。一个 Java 对象到底有多大?想要精确计算一个 Java 对象占用的内存,首先要了解 Java 对象的结构表示。Java 对象结构一个 Java...

weixin_39624360的博客 324

wsl2内核版本和模块版本不一致解决方法

** /lib/modules/…build: No such file or directory错误解决办法这篇文章历时1个月整,从4月5日一直到5月5日,这一问题才得以解决。

m0_60634555的博客 5105

面试官:从 MySQL 读取 100w 数据进行处理,应该怎么做?问倒一大片!

分库分表场景下,单个表的查询结果集虽然不大,但如果某个查询跨了多个库多个表,又要做结果集的合并、排序等动作,依然有可能撑爆内存;当查询百万级的数据的时候,还可以使用游标方式进行数据查询处理,不仅可以节省内存的消耗,而且还不需要一次性取出所有数据,可以进行逐条处理或逐条取出部分批量处理。如果没有流式查询,我们想要从数据库取 100w 条记录而又没有足够的内存时,就不得不分页查询,而分页查询效率取决于表设计,如果设计的不好,就无法执行高效的分页查询。流式查询:内存会保持稳定,不会随着记录的增长而增长。

2301_78588786的博客 3342

手把手教你用STM32CubeMX配置I3C通信(含动态地址分配实战)

本文提供了一份基于STM32CubeMX配置I3C通信的实战指南,重点讲解了动态地址分配的实现步骤。通过详细的工程配置、从设备枚举、CCC命令使用及数据读写示例,帮助开发者快速掌握这一高效通信协议,以替代传统的I2C或SPI接口,满足多传感器连接与低功耗设计需求。

c8d9e0f1的博客 546

YOLOv8剪枝实战:基于torch_pruning的模型优化与性能提升指南

本文详细介绍了如何使用torch_pruning工具对YOLOv8模型进行结构化剪枝,以实现模型轻量化与性能提升。通过实战步骤解析,包括环境搭建、依赖图分析、迭代剪枝与微调策略,帮助开发者有效减少模型参数量和计算量,提升在边缘设备上的推理速度,同时保持检测(detect)与分割(segment)任务的精度。

water的专栏 1123

100万条数据占用多少空间

比如你数据库某一张表有三个字段:一个long型,一个varchar(100) 型,一个date型。 long型占用8个字节(一个字节8位),data占用8字节。 那么一行占用:8+100+8=116Byte。 那么100万行,大约有110M。这是三列。如果你是10列,你就可以粗略估计出来了...

jing_xin的专栏 4万+

Unity游戏开发:从零开始适配Nintendo Switch的完整指南

本文详细介绍了如何使用Unity进行Nintendo Switch游戏开发的完整流程,包括开发环境搭建、Unity工程适配、手柄与硬件特性开发、存储与性能优化等关键步骤。特别强调了Switch SDK的配置、输入系统改造和内存优化技巧,帮助开发者高效完成跨平台适配。

vodka的博客 1073

新来的妹纸问我,如果把几百万数据放入内存,会不会把系统撑爆?

上一篇:深夜看了张一鸣的微博,让我越想越后怕作者:不学无数的程序员链接:https://www.jianshu.com/p/412f68485606在公司有一个需求是要核对一批数据,之前的...

emprere的博客 432

STM32H750实战:用TIM+DMA驱动ADC/DAC实现音频回环(附CubeMX配置避坑指南)

本文详细介绍了在STM32H750上构建高保真、低延迟音频链路的实战方法。通过配置TIM定时器作为硬件节拍器,精准触发ADC采集与DAC播放,并利用DMA实现数据的自动搬运,全程无需CPU干预。文章重点剖析了CubeMX配置中的关键步骤与常见“坑点”,如ADC的Conversion Data Management模式选择、DMA的FIFO与Burst模式配置,以及STM32H7系列必须开启ADC全局中断等,并提供了完整的代码实现与调试验证指南。

1057

STM32 伺服电机 指令脉冲+方向位置控制模式 主从定时器 实现PWM脉冲数精确控制

实验室有个项目涉及到多个步进电机以及伺服电机的控制,需要电机得到一个触发信号后精确移动一段距离。 下面以单个伺服电机控制为例,利用伺服电机的指令脉冲加方向位置控制模式实现jing'que ...

phcdd的博客 2万+

内存中有两个4字节以压缩的bcd_几百万数据放入内存不会把系统撑爆吗?

在公司有一个需求是要核对一批数据,之前的做法是直接用 SQL 各种复杂操作给怼出来的,不仅时间慢,而且后期也不好维护,就算原作者来了过一个月估计也忘了 SQL 什么意思了,于是有一次我就想着问一下之前做这个需求的人为什么不将这些数据查出来后在内存里面做筛选呢?直接说了你不怕把内存给撑爆吗?此核算服务器是单独的服务器,配置是四核八 G 的,配置堆的大小是 4G。本着怀疑的精神,就想要弄清楚几百万条数...

weixin_39843738的博客 124

【拼多多笔试题汇总】2024-03-24-拼多多春招笔试题

A 小镇上有个奇特的游戏。游戏开始时,A 先生准备了一排 nnn 个物品。K 小姐和卢小姐则轮流进行操作。首先,K 小姐可以选择移除至多 xxx 个物品。接着,卢小姐也可以选择移除剩余物品中的至多 yyy 个。游戏的目标是,K 小姐想尽量让剩余物品的价值之和最大化,而卢小姐则想将剩余物品的价值之和最小化。假设两人都采取最优策略,请问最后剩余物品的价值之和是多少?第一行包含五个正整数 n,m,k,x,yn, m, k, x, yn,m,k,x,y,分别表示物品的总数、K 小姐最多可移除的物品数、卢小姐最多可移

春秋招笔试突围 1万+

stringbuidle会不会内存泄露_几百万数据放入内存会不会把系统撑爆?

在公司有一个需求是要核对一批数据,之前的做法是直接用SQL各种复杂操作给怼出来的,不仅时间慢,而且后期也不好维护,就算原作者来了过一个月估计也忘了SQL什么意思了,于是有一次我就想着问一下之前做这个需求的人为什么不将这些数据查出来后在内存里面做筛选呢?直接说了你不怕把内存给撑爆吗?此核算服务器是单独的服务器,配置是四核八G的,配置堆的大小是4G。本着怀疑的精神,就想要弄清楚几百万条数据真...

weixin_39842955的博客 109

YOLOv11改进策略【损失函数篇】| 通过辅助边界框计算IoU提升检测效果(Inner_GIoU、Inner_DIoU、Inner_CIoU、Inner_EIoU、Inner_SIoU)

为了弥补现有 IoU 损失在不同检测任务中泛化性弱和收敛速度慢的问题,·Inner-IoU·通过引入比例因子 “ratio” 来控制辅助边界框的尺度大小,利用不同尺度的辅助边界框来计算损失,从而加速边界框回归过程。

Limiiiing的博客 3893

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

gorm存指针数据_几百万数据放入内存会不会把系统撑爆?

在公司有一个需求是要核对一批数据,之前的做法是直接用SQL各种复杂操作给怼出来的,不仅时间慢,而且后期也不好维护,就算原作者来了过一个月估计也忘了SQL什么意思了,于是有一次我就想着问一下之前做这个需求的人为什么不将这些数据查出来后在内存里面做筛选呢?直接说了你不怕把内存给撑爆吗?此核算服务器是单独的服务器,配置是四核八G的,配置堆的大小是4G。本着怀疑的精神,就想要弄清楚几百万条数据真...

weixin_34552961的博客 278

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

byte数组添加数据_几百万数据放入内存不会把系统撑爆吗?

01 计算机的存储单位计算机的存储单位常用的有bit、Byte、KB、MB、GB、TB后面还有但是我们基本上用不上就不说了,我们经常将bit称之为比特或者位、将Byte简称为B或者字节,将KB简称为K,将MB称之为M或者兆,将GB简称为G。那么他们的换算单位是怎样的呢?1.1 换算关系首先我们得知道在计算机中所有数据都是由0 1来组成的,那么存储0 1这些二进制数据是由什么存放呢?就是由bit存放...

weixin_39810856的博客 446

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

会不会导致内存泄漏_几百万数据放内存会不会把系统撑炸?

作者:不学无数的程序员链接:juejin.im/post/5dfddb73f265da33d912e412公司有一个需求是要核对一批数据,之前的做法是直接用SQL各种复杂操作给怼出来的,不仅时间慢,而且后期也不好维护,就算原作者来了过一个月估计也忘了SQL什么意思了,于是有一次我就想着问一下之前做这个需求的人为什么不将这些数据查出来后在内存里面做筛选呢?直接说了你不怕把内存给撑爆吗?此核...

weixin_39883462的博客 430

新来的妹子把几百万数据放入了内存,系统立马爆了

点击上方“java大数据修炼之道”,选择“设为星标”优质文章, 第一时间送达上一篇:JVM 史上最最最完整深入解析作者:不学无数的程序员my.oschina.net/u/4030990/...

hello world! 400

stringbuidle会不会内存泄露_几百万数据放内存会不会把系统撑炸?

作者:不学无数的程序员链接:juejin.im/post/5dfddb73f265da33d912e412公司有一个需求是要核对一批数据,之前的做法是直接用SQL各种复杂操作给怼出来的,不仅时间慢,而且后期也不好维护,就算原作者来了过一个月估计也忘了SQL什么意思了,于是有一次我就想着问一下之前做这个需求的人为什么不将这些数据查出来后在内存里面做筛选呢?直接说了你不怕把内存给撑爆吗?此核...

weixin_39607798的博客 86

vc++64位系统下long的长度为4个字节_新来的妹子把几百万数据放入了内存,系统立马爆了...

点击上方蓝色字体,选择“标星公众号”优质文章,第一时间送达上一篇:这300G的Java资料是我师傅当年给我的,免费分享给大家下一篇:这200G的Java实战资料是我师傅当年教我的第作者:不学无数的程序员my.oschina.net/u/4030990/blog/3145683在公司有一个需求是要核对一批数据,之前的做法是直接用SQL各种复杂操作给怼出来的,不仅时间慢,而且后期也不好维护,...

weixin_39957647的博客 206

vc++64位系统下long的长度为4个字节_小实验:一次性把几百万数据放入内存,系统会撑爆吗?...

作者:不学无数的程序员链接:https://urlify.cn/UFZJBf在公司有一个需求是要核对一批数据,之前的做法是直接用SQL各种复杂操作给怼出来的,不仅时间慢,而且后期也不好维护,就算原作者来了过一个月估计也忘了SQL什么意思了,于是有一次我就想着问一下之前做这个需求的人为什么不将这些数据查出来后在内存里面做筛选呢?直接说了你不怕把内存给撑爆吗?此核算服务器是单独的服务器,配置...

weixin_39710251的博客 282
上一篇: 为什么要放弃 JSP ?
下一篇: 别用Date了,Java8新特性之日期处理,现在学会也不迟!
Java思维导图
博客等级 码龄10年 306粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值