当前位置: 首页 > news >正文

STL-空间配置器的了解

前言

        空间配置器,顾名思义就是为了各个容器高效的管理空间(空间的申请与回收)的,在默默的工作的。虽然在常规上使用STL时,可能用不上它,但是站在学习研究的角度,学习它的实现原理对我们有很大的帮助。

目录

1.为什么需要空间配置器

2.SGI—STL空间配置器实现原理

3.一级空间配置器实现原理

        3.1 一级空间配置器

        3.2 二级空间配置器

                3.2.1内存池

                3.2.2 SGI-STL中二级空间配置器设计

        3.3 SGI-STL二级空间配置器之空间申请

                3.3.1前期的准备

                3.3.2申请空间

                        3.3.2.1填充内存块

                        3.3.2.2向内存池中索要空间

                3.3.3空间的回收

        3.4 空间配置器的默认选择

        3.5 空间配置器的再次封装

        3.6 对象的构造和释放

        


1.为什么需要空间配置器

        new申请的空间,虽然可以使用,但是有以下不足之处:

        1.空间申请与释放需要用户自己管理,容易造成内存泄露 

        2.频繁向系统申请小块内存块,容易造成内存碎片

        3.频繁向系统系统申请小块内存,影响程序运行效率

        4.直接使用malloc和new进行申请每块空间前有额外空间浪费

        5.申请失败如何应对

        6.代码结构比较混乱,代码复用率不高

        7.未考虑线程安全问题

        由于存在这些问题,因此需要一块高效的的内存管理机制。 

2.SGI—STL空间配置器实现原理

        频繁的向系统申请小块内存会有很多的问题,那么怎么样的内存算是小块内存呢?

        SGI-STL以128作为大内存和小内存的分界线,将空间配置器分为两级结构,一级空间配置器处理大块内存,二级空间配置器处理小块内存。 

3.一级空间配置器实现原理

        3.1 一级空间配置器

        一级空间配置器的原理非常简单,直接对malloc和free进行了封装,并增加了C++中set_new_handle思想。

namespace qyy
{template <int inst>class __malloc_alloc_template{private:static void* oom_malloc(size_t);public://对malloc进行封装static void* allocate(size_t n){//申请空间成功直接返回,失败了交给oom_malloc处理void* result = malloc(n);if (result == 0){result = oom_malloc(n);}return result;}//对free进行封装static void* deallocate(void* p, size_t){free(p);}//模拟实现set_malloc_handler//该函数参数为函数指针,返回值也是函数指针//void(*set_malloc_handler(void*(f*)( )  )) ()static void (*set_malloc_hander(void (*f)()))(){void (*old)() = __malloc_alloc_oom_handler;__malloc_alloc_oom_handler = f;return (old);}};//malloc空间申请失败时调用该函数template<int inst>void* __malloc_alloc_template<inst>::oom_malloc(size_t){void(*my_malloc_handler)();void* result;for (;;){//检测用户是否设置空间不足应对措施,如果没有设置,抛异常模拟new的方式my_malloc_handler = __malloc_alloc_handler;if (0 == my_malloc_handler){__THROW_BAD_ALLOC;}//如果设置了,执行用户提供空间不足应对措施(*my_malloc_handler)();//继续申请空间可能就会成功result = malloc(n);if (result)return (result);}}typedef __malloc_alloc_template<0> malloc_alloc;}

        3.2 二级空间配置器

        二级空间配置器是专门负责处理小于128字节的小块空间。如何才能提升小块内存的的申请和释放的方式呢?SGI-STL采用了内存池的技术来提高申请空间的速度以及减少额外的空间的浪费,采用哈希桶的方式来提高用户获取空间的速度与高效管理。 

                3.2.1内存池

        内存池就是:先申请一块比较大的内存当做备用,当需要内存时,直接去内存池中拿内存就好了,当内存池中的空间不够时,再向内存中取,当用户不用时,直接还回内存池即可。避免了频繁的向系统申请小块内存所造成的效率低,内存碎片以及额外浪费的问题。 

                3.2.2 SGI-STL中二级空间配置器设计

        SGI-STL中的二级空间配置器使用了内存池技术,但是没有采用链表的方式对用户已归还的空间进行管理(因为用户申请空间时是在查找合适的小块内存时效率较低),而采取哈系桶的方式进行管理。那么是否128个桶来管理已归还的空间呢?答案是不需要的,因为用户申请空间基本上都是按照4的整数倍来申请的,其他大小的空间基本很少用到,因此:SGI-STL将用户申请的内存块向上对其到了8的整数倍。  

        3.3 SGI-STL二级空间配置器之空间申请

                3.3.1前期的准备

namespace qyy
{template<int inst>class __default_alloc_template{private:enum {__ALIGN = 8};//如果用户需要的内存不是8的整数倍,向上对其到8的整数倍enum {__MAX_BYTES = 128};//大小块内存的分界线enum { __NFREELISTS = __MAX_BYTES / __ALIGN };//采用哈希桶保存小块内存时所需要的内存个数static size_t ROUND_UP(size_t bytes){return (((bytes)+__ALIGN - 1) & ~(ALIGN - 1));}private://用联合图来维护链表结构union obj{union obj* free_list_link;char client_data[1];};private:static obj* free_list[__NFREELISTS];//哈希函数根据用户提供的字节数找到对应的桶号static size_t FREELIST_INDEX(size_t bytes){return (((bytes)+__ALIGN - 1) / ALING - 1);}//start_free 和end_free用来标记内存池中大块内存的起始和末尾位置static char* start_free;static char* end_free;//用来记录该空间配置器已经向系统索要了多少的块内存static size_t heap_size;///...};
}

                3.3.2申请空间

//函数功能:向空间配置器索要空间//参数n:所需要的空间字节数//返回值:返回空间的首地址static void* allocate(size_t n){obj* __VOLATILE* my_free_list;obj* __RESTRICT result;//检测用户所需要的空间是否在超过128字节(即是否为小块内存)if (n > (size_t)__MAX_BYTES){//不是小块内存交给一级空间配置器来处理return (malloc_alloc::allocate(n));}//根据用户所需要的字节找到对应的桶号my_free_list = free_list + FREELIST_INDEX(n);result = *my_free_list;//如果桶里面没有内存块,向桶里面补充内存块if (result == 0){//n将向上对齐到8的整数倍,保证向桶里面补充内存块时,内存块一定是8的整数倍void* r = refill(ROUND_UP(n));return r;}//维护桶里面剩余内存块的链式关系*my_free_list = result->free_lsit_link;return (result);}

                        3.3.2.1填充内存块

		//函数功能:向哈系桶里面补充空间//参数n小块内存//首个小块内存的首地址template<int inst>void* __default_alloc_template<inst>::refill(size_t n){//一次性向内存池索要20个n字节的空间int nobjs = 20;char* chunk = chunk_alloc(n, nobjs);obj** my_free_list;obj* result;obj* current_obj, * next_obj;int i;//如果只有一块直接返回给用户if (1 == nobjs)return (chunk);//找到对应的桶号my_free_list = free_list + FREELIST_INDEX(n);//将第一块返回给用户,去其他的挂到哈系桶中result = (obj*)chunk;*my_free_list = next_obj = (obj*)(chunk + n);for (i = 1;;i++){current_obj = next_obj;next_obj = (obj*)((char*)next_obj + n);if (nobjs - 1 == i){current_obj->free_list_link = 0;break;}else{current_obj->free_list_link = next_obj;}}return (result);}

                        3.3.2.2向内存池中索要空间

 

	    template<int inst>char* __default_alloc_tempalte<inst>::chunk_alloc(size_t size, int& nobjs){//计算nobjs个size字节内存块的总大小以及内存池中剩余空间的总大小char* result;size_t total_bytes = size * nobjs;size_t bytes_left = end_free - start_free;//如果内存池可以提供total_bytes字节,返回if (bytes_left >= tatal_bytes){result = start_free;start_free += tatal_bytes;return (result);}else if (bytes_left >= size){//nobjs块无法提供,但是至少可以提供1块size字节的内存块,提供后返回nobjs = bytes_left / size;tatal_byte = size * nobjs;result = start_free;start_free += tatal_bytes;return (result);}else{//内存池空间不够连一小块内存都没有。//向系统堆求助,往内存池中补充空间//计算向内存中补充空间的大小:本次空间总大小的两倍 + 向系统申请总大小/16size_t bytes_to_get = 2 * tatal_byte + ROUND_UP(heap_size >> 4);//如果内存池有剩余空间(该空间一定是8的整数倍)将该空间挂到对应的哈希桶中if (bytes_left > 0){//找到对应的哈系桶obj** my_free_list = free_list + FREELIST_INDEX(bytes_left);((obj*)start_free)->free_list_link = *my_free_list; )* my_ree_list = (obj*)start_free;}//通过系统堆向内存池补充空间,如果补充成功,递归继续分配start_free = (char*)malloc(bytes_to_get);if (0 == start_free){//通过系统堆补充失败,在哈系桶中寻找是否有没有使用的较大块内存int i;obj** my_free_list, * p;for (i = size; i <= __MAX_BYTES;i += __ALIGN){my_free_list = free_list + FREELIST_INDEX(i);p = *my_free_list;//如果有,将该内存块补充进内存池,递归继续分配if (0 != p){*my_free_list = p->free_list_link;start_free = (char*)p;end_free = start_free + i;return (chunk_alloc(size, nobjs));}}//山穷水尽,只能向一级空间配置器求助//注意:此处一定要将end_free置空,因为一级空间配置器一旦抛异常就会出问题end_free = 0;start_free = (char*)malloc_alloc::allocate(bytes_to_get);}heap_size += bytes_to_get;end_free = start_free + bytes_to_get;return (chunk_alloc(size, nobjs));}}

                3.3.3空间的回收

		//函数功能:用户将空间归还给空间配置器//参数:p空间首地址 n空间总大小static void deallocate(void* p, size_t n){obj* q = (obj*)p;obj** my_free_list;if (n > (size_t)__MAX_BYTES){malloc_alloc::deallocate(p, n);return;}//找到对应的哈系桶,将内存挂到哈系桶中my_free_list=free_list+ FREELIST_INDEX(n);q->free_list_link = *my_free_list;*my_free_list = q;}

        3.4 空间配置器的默认选择

        SIG_STL默认使用一级空间配置器 还是二级空间配置器,是通过宏开关USE_MALLOC宏进行控制的。

         在SGI_STL中没有定义这个宏所以,默认情况下SGI_STL使用二级空间配置器。

        3.5 空间配置器的再次封装

        在C++中,用户所需要的空间可能是任意类型的,有单个对象的空间,有连续空间,每一次都让用户自己计算空间的总大小不是很友好,因此SGI_STL将空间配置器重新封装了一层。

template<class T,class ALLOC>class simlpe_alloc{public://申请n个T类型对象大小的空间static T* allocate(size_t n){return 0 == n ? 0 : (T*)ALLOC::allocte(n * sizeof(T));}//申请一个T类型对象大小的空间static T* allocate(void){return (T*)ALLOC::allocate(sizeof(T));}//释放n个T类型对象大小的空间static void deallocate(T* p, size_t n){if (0 != n){ALLOC::deallocate(p, n * sizeof(T));}}static void deallocate(T* p){ALLOC::deallocate(p, sizeof(T));}

 

        3.6 对象的构造和释放

        因为效率的需要,SGI_STL决定将空间的申请和释放和对象的构造析构两个过程分离,因为有些对象的构造不需要调用构造函数,销毁时不需要调用析构函数,将该过程分离可以提高程序的性能。

	//归还空间时,先调用析构函数进行资源的清理template <class T>inline void destory(T* pointer){pointer->~T();}//空间申请好后,调用该函数:利用placement-new完成对对象的构造template<class T1,class T2>inline void construct(T1* p, const T2& value){new(p)T1(value);}

         注意,在释放对象时,需要根据对象的类型来确定是否需要调用析构函数(类型萃取)

        对象的类型可以通过迭代器萃取到。

        这些内容难度较大作为了解就可以了。(对于初学者来说) 

 

        

相关文章:

STL-空间配置器的了解

前言 空间配置器&#xff0c;顾名思义就是为了各个容器高效的管理空间&#xff08;空间的申请与回收&#xff09;的&#xff0c;在默默的工作的。虽然在常规上使用STL时&#xff0c;可能用不上它&#xff0c;但是站在学习研究的角度&#xff0c;学习它的实现原理对我们有很大的…...

哔哩哔哩 B站 bilibili 视频视频音效调节 清澈人声

视频音效调节方式&#xff1a;直接视频播放内容界面内鼠标右键点击视频音效调节 注意&#xff1a;需要使用的是谷歌浏览器&#xff0c;我的火狐浏览器试了不行&#xff0c;都没选项&#xff0c;火狐的出来的界面是这样的&#xff1a; 目录 具体操作如下&#xff1a; 1、谷歌…...

下一代存储解决方案:湖仓一体

文章首发地址 湖仓一体是将数据湖和数据仓库相结合的一种数据架构&#xff0c;它可以同时满足大数据存储和传统数据仓库的需求。具体来说&#xff0c;湖仓一体可以实现以下几个方面的功能&#xff1a; 数据集成&#xff1a; 湖仓一体可以集成多个数据源&#xff0c;包括结构…...

IntelliJ IDEA 2023.2.1 修复版本日志

我们刚刚发布了 v2023.2 的第一个错误修复更新。 您可以从 IDE 内部、使用工具箱应用程序或通过快照&#xff08;如果您使用的是 Ubuntu&#xff09;更新到此版本。您也可以直接从我们的网站下载。 以下是最新版本中包含的最值得注意的改进和修复的列表&#xff1a; 我们已经解…...

算法通关村十三关 | 数组字符串加法专题

1. 数组实现整数加法 题目&#xff1a;LeetCode66&#xff0c;66. 加一 - 力扣&#xff08;LeetCode&#xff09; 思路 我们只需要从头到尾依次运算&#xff0c;用常量标记是否进位&#xff0c;需要考虑的特殊情况是digits [9,9,9]的时候进位&#xff0c;我们组要创建长度加1…...

k8s--基本概念理解

必填字段 在要创建的 Kubernetes 对象的文件中.yaml&#xff0c;您需要设置以下字段的值&#xff1a; apiVersion- 您使用哪个版本的 Kubernetes API 创建此对象 kind- 你想创建什么样的对象 metadata- 有助于唯一标识对象的数据&#xff0c;包括name字符串、UID和可选namesp…...

流媒体开发千问【持续更新】

H.264中IDR帧和I帧区别 H.264/AVC编码标准中&#xff0c;IDR帧和I帧都是关键帧&#xff0c;即它们都不依赖于其他帧进行解码。但是&#xff0c;它们之间存在明确的区别&#xff1a; 定义与功能&#xff1a; I帧&#xff08;Intra-frame&#xff09;&#xff1a;I帧是一个内部编…...

全球各国官方语言大盘点,英语不得不学哇。。。

因国家和地区范围界定不同&#xff0c;官方语言只是个相对概念。具体而言是一个国家通用的正式语言或认定的正式语言。它是为适应管理国家事务的需要&#xff0c;在国家机关、正式文件、法律裁决及国际交往等官方场合中规定一种或几种语言为有效语言的现象。官方语言也是一个国…...

【mq】如何保证消息可靠性

文章目录 mq由哪几部分组成rocketmqkafka 为什么需要这几部分nameserver/zookeeper可靠性 broker可靠性 生产者消费者 mq由哪几部分组成 rocketmq kafka 这里先不讨论Kafka Raft模式 比较一下&#xff0c;kafka的结构和rocketmq的机构基本上一样&#xff0c;都需要一个注册…...

疲劳检测-闭眼检测(详细代码教程)

简介 瞌睡经常发生在汽车行驶的过程中&#xff0c;该行为害人害己&#xff0c;如果有一套能识别瞌睡的系统&#xff0c;那么无疑该系统意义重大&#xff01; 实现步骤 思路&#xff1a;疲劳驾驶的司机大部分都有打瞌睡的情形&#xff0c;所以我们根据驾驶员眼睛闭合的频率和…...

大数据日常运维命令

1、HDFS NameNode /usr/local/fqlhadoop/hadoop/sbin/hadoop-daemon.sh start namenode /usr/local/fqlhadoop/hadoop/sbin/hadoop-daemon.sh stop namenode bin/hdfs haadmin -DFSHAAdmin -getServiceState n1 2、HDFS DataNode /usr/local/fqlhadoop/hadoop/sbin/hadoop-…...

解锁安全高效办公——私有化部署的WorkPlus即时通讯软件

在当今信息时代&#xff0c;高效的沟通与协作对于企业的成功至关重要。然而&#xff0c;随着信息技术的发展&#xff0c;保护敏感信息和数据安全也变得越来越重要。为了满足企业对于安全沟通和高效办公的需求&#xff0c;我们隆重推出私有化部署的WorkPlus即时通讯软件&#xf…...

IDEA使用git

文章目录 给所有文件配置git初始化本地仓库创建.gitignore文件添加远程仓库分支操作 给所有文件配置git 初始化本地仓库 创建.gitignore文件 添加远程仓库 分支操作 新建分支 newbranch 切换分支 checkout 推送分支 push 合并分支 merge...

【跟小嘉学 Rust 编程】十八、模式匹配(Patterns and Matching)

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...

keepalived+lvs+nginx高并发集群

keepalivedlvsnginx高并发集群 简介&#xff1a; keepalivedlvsnginx高并发集群&#xff0c;是通过LVS将请求流量均匀分发给nginx集群&#xff0c;而当单机nginx出现状态异常或宕机时&#xff0c;keepalived会主动切换并将不健康nginx下线&#xff0c;维持集群稳定高可用 1.L…...

剑指Offer65.不用加减乘除做加法 C++

1、题目描述 写一个函数&#xff0c;求两个整数之和&#xff0c;要求在函数体内不得使用 “”、“-”、“*”、“/” 四则运算符号。 示例: 输入: a 1, b 1 输出: 2 2、VS2019上运行 使用位运算的方法 #include <iostream>class Solution { public:/*** 计算两个整…...

【linux命令讲解大全】004.探索Linux命令行中的chmod和chown工具

文章目录 chmod概要主要用途参数选项返回值例子 chown补充说明语法选项参数实例 从零学 python chmod 用来变更文件或目录的权限 概要 chmod [OPTION]... MODE[,MODE]... FILE... chmod [OPTION]... OCTAL-MODE FILE... chmod [OPTION]... --referenceRFILE FILE...主要用途…...

nginx会话保持

ip_hash:通过IP保持会话 作用&#xff1a; nginx通过后端服务器地址将请求定向的转发到服务器上。 将客户端的IP地址通过哈希算法加密成一个数值 如果后端有多个服务器&#xff0c;第一次请求到服务器A&#xff0c; 并在务器登录成功&#xff0c;那么再登录B服务器就要重新…...

SpringBoot使用Druid连接池 + 配置监控页面(自定义版 + starter版)

目录 1. Druid连接池的功能2. 自定义版2.1 pom.xml添加依赖2.2 MyDataSourceConfig实现2.3 application.properties配置编写Controller进行测试2.4 druid监控页面查看 3. starter版3.1 pom.xml添加依赖3.2 自动配置分析3.3 使用application.properties对druid进行配置3.4 druid…...

【业务功能篇77】微服务-OSS对象存储-上传下载图片

3. 图片管理 文件存储的几种方式 单体架构可以直接把图片存储在服务器中 但是在分布式环境下面直接存储在WEB服务器中的方式就不可取了&#xff0c;这时我们需要搭建独立的文件存储服务器。 3.1 开通阿里云服务 针对本系统中的相关的文件&#xff0c;图片&#xff0c;文本等…...

【CSS 常用加载动画效果】

常用加载效果 呼吸灯效果波浪光效果转圈加载 呼吸灯效果 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><div id"ti"></div></body><style>b…...

python 模块requests 发送 HTTP 请求

一、简介 requests 模块是 python 基于 urllib&#xff0c;采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便&#xff0c;可以节约我们大量的工作 二、安装 pip install requestsimport requests三、方法 requsts.requst(method, url,headers,cookies,prox…...

关于 Camera 预览和录像画质不一样的问题分析

1、问题背景 基于之前安卓平台的一个项目&#xff0c;客户有反馈过一个 Camera app 预览的效果&#xff0c;和录像效果不一致的问题。 这里的预览是指打开 Camera app 后直接出图的效果&#xff1b;录像的效果则是指打开 Camera app 开启录像功能&#xff0c;录制一段视频&…...

【音视频】 视频的播放和暂停,当播放到末尾时触发 ended 事件,循环播放,播放速度

video 也可以 播放 MP3 音频&#xff0c;当不想让 视频显示出来的话&#xff0c;可以 给 video 设置宽和高 1rpx &#xff0c;不可以隐藏 <template><view class"form2box"><u-navbar leftClick"leftClick"><view slot"left&q…...

Python数据分析高薪实战第一天 python基础与项目环境搭建

开篇词 数据赋能未来&#xff0c;Python 势不可挡 互联网公司从红利下的爆发期&#xff0c;进入新的精细化发展阶段&#xff0c;亟须深入分析与挖掘业务与数据价值&#xff0c;从而找到新的增长点突破现有增长瓶颈。各行各业的数据分析需求井喷&#xff0c;数据分析人才成为争…...

pandas数据分析——groupby得到分组后的数据

groupbyagg分组聚合对数据字段进行合并拼接 Pandas怎样实现groupby聚合后字符串列的合并&#xff08;四十&#xff09; groupby得到分组后的数据 pandas—groupby如何得到分组里的数据 date_range补齐缺失日期 在处理时间序列的数据中&#xff0c;有时候会遇到有些日期的数…...

Android studio 软件git使用

在 test 分支添加的方法 , 现在切换到 master分支 总共 2 个分支 , 当前的分支是 test 出现了 先试一下 force checkout , 尝试之后发现 , 你更改没有带过来 , 以为哪个类在master分支没有 , 所以这边也没有 , 切回分支 test 发现之前的跟改没有 , 这样即可以找回 继续切换…...

通过C实现sqlite3操作,导入电子词典

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sqlite3.h> int main(int argc, const char *argv[]) {//创建并打开一个数据库sqlite3 *db NULL;if(sqlite3_open("./dict.db",&db) ! SQLITE_OK){printf("…...

K8S集群中使用JDOS KMS服务对敏感数据安全加密 | 京东云技术团队

基本概念 KMS&#xff0c;Key Management Service&#xff0c;即密钥管理服务&#xff0c;在K8S集群中&#xff0c;以驱动和插件的形式启用对Secret&#xff0c;Configmap进行加密。以保护敏感数据&#xff0c; 驱动和插件需要使用者按照需求进行定制和实现自己的KMS插件&…...

SpringBoot+quartz实现定时任务的创建、删除、查询操作

1、在pom.xml文件中导入quartz的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency> 2、配置quartz的数据源等操作 package com.train.batch.config;imp…...

视频网站切片怎么做/nba西部最新排名

原标题&#xff1a;这款加速器可以帮你免费解决LOL手游下载、账号注册、更新慢的一系列问题不少小伙伴们已经开玩英雄联盟手游了&#xff0c;由于国服目前还没有动静&#xff0c;现在能玩的都是海外服&#xff0c;如此一来就会产生一个问题&#xff0c;就是手游版LOL更新慢怎么…...

客厅装修风格/乐陵seo优化

小试牛刀 WiFi 远控 wendu 废话 少说 直接上代码 DH11三根线 信号线 接2 WiFi 模块 r-------t t--------r en&vcc------3.3v剩下的 共地的啦 double Fahrenheit(double celsius) { return 1.8 * celsius 32; } //摄氏温度度转化为华氏温度 double Kelvin(doubl…...

国外购物网站推荐/深圳百度关键词

实验结论 如果需要在循环结束后获得结果&#xff0c;推荐列表解析&#xff1b; 如果不需要结果&#xff0c;直接使用for循环, 列表解析可以备选; 除了追求代码优雅和特定规定情境&#xff0c;不建议使用map 如果不需要返回结果 这里有三个process, 每个任务将通过增加循环提高时…...

微网站建设开发/上海seo搜索优化

这是一个iPhone Menu JSON文件的示例&#xff0c;您可能会看到该文件用于存储菜单配置设置以在移动设备上设置网站。 使用简单的JSON格式&#xff0c;可以轻松地在移动和Web组件之间共享它。 另外&#xff1a; 请参阅更多JSON示例。 {"menu": {"header": &…...

许昌抖音推广公司/嘉兴seo外包

***利用了Facebook平台上的一个漏洞&#xff0c;令将近5000万个Facebook账户的访问令牌面临被窃取的风险。访问令牌是一种数字密钥&#xff0c;能让用户在每次使用Facebook时都不用重新输入密码。Facebook工程师周二发现了漏洞&#xff0c;它存在于Facebook的View As功能中&…...

番禺做网站600元/seo研究协会网

写在文章之前&#xff1a;博友们&#xff0c;你的支持是我最大的动力&#xff0c;在阅读我文章的同时&#xff0c;也请为我投上你宝贵的一票&#xff0c;谢谢。 投票请进&#xff1a;http://2010blog.51cto.com/855319 &#xff0d;&#xff0d;&#xff0d;&#xff0d;&#…...