零拷贝原理

零拷贝原理

零拷贝(Zero-copy)技术指在计算机执行操作时,CPU 不需要先将数据从一个内存区域复制到另一个内存区域,从而可以减少上下文切换以及 CPU 的拷贝时间。它的作用是在数据报从网络设备到用户程序空间传递的过程中,减少数据拷贝次数,减少系统调用,实现 CPU 的零参与,彻底消除 CPU 在这方面的负载。实现零拷贝用到的最主要技术是 DMA 数据传输技术和内存区域映射技术。 零拷贝机制可以减少数据在内核缓冲区和用户进程缓冲区之间反复的 I/O 拷贝操作。 零拷贝机制可以减少用户进程地址空间和内核地址空间之间因为上下文切换而带来的 CPU 开销。 1. 物理内存和虚拟内存 由于操作系统的进程与进程之间是共享 CPU 和内存资源的,因此需要一套完善的内存管理机制防止进程之间内存泄漏的问题。为了更加有效地管理内存并减少出错,现代操作系统提供了一种对主存的抽象概念,即是虚拟内存(Virtual Memory)。虚拟内存为每个进程提供了一个一致的、私有的地址空间,它让每个进程产生了一种自己在独享主存的错觉(每个进程拥有一片连续完整的内存空间)。 1.1. 物理内存 物理内存(Physical memory)是相对于虚拟内存(Virtual Memory)而言的。物理内存指通过物理内存条而获得的内存空间,而虚拟内存则是指将硬盘的一块区域划分来作为内存。内存主要作用是在计算机运行时为操作系统和各种程序提供临时储存。在应用中,自然是顾名思义,物理上,真实存在的插在主板内存槽上的内存条的容量的大小。 1.2. 虚拟内存 虚拟内存是计算机系统内存管理的一种技术。 它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间)。而实际上,虚拟内存通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换,加载到物理内存中来。 目前,大多数操作系统都使用了虚拟内存,如 Windows 系统的虚拟内存、Linux 系统的交换空间等等。 虚拟内存地址和用户进程紧密相关,一般来说不同进程里的同一个虚拟地址指向的物理地址是不一样的,所以离开进程谈虚拟内存没有任何意义。每个进程所能使用的虚拟地址大小和 CPU 位数有关。在 32 位的系统上,虚拟地址空间大小是 2 ^ 32 = 4G,在 64位系统上,虚拟地址空间大小是 2 ^ 64= 2 ^ 34G,而实际的物理内存可能远远小于虚拟内存的大小。每个用户进程维护了一个单独的页表(Page Table),虚拟内存和物理内存就是通过这个页表实现地址空间的映射的。下面给出两个进程 A、B 各自的虚拟

UDP 组播---你需要了解这些

UDP 组播---你需要了解这些

先来了解下UDP UDP 是UserDatagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。 UDP和TCP的区别:http://blog.csdn.net/ljheee/article/details/50823050 UDP详解:http://blog.csdn.net/ljheee/article/details/51720594 UDP信息传递的方式分三类 ① 单播Unicast:是客户端与服务器之间的点到点连接。 ② 广播BroadCast:主机之间“一对所有”的通讯模式,广播者可以向网络中所有主机发送信息。广播禁止在Internet宽带网上传输(广播风暴)。 ③ 多播MultiCast:主机之间“一对一组”的通讯模式,也就是加入了同一个组的主机可以接受到此组内的所有数据。 这里需要注意的是:只有UDP才有广播、组播的传递方式;而TCP是一对一连接通信。多播的重点是高效的把同一个包尽可能多的发送到不同的,甚至可能是未知的设备。但是TCP连接是一对一明确的,只能单播。 在Java API中,实现UDP方式的编程,包含客户端网络编程和服务器端网络编程,主要由两个类实现,分别是:DatagramSocket和DatagramPacket。 关于UDP使用的详细例子:https://github.com/ljheee/ChatUDP UDP组播 组播报文的目的地址使用D类IP地址, D类地址不能出现在IP报文的源IP地址字段。单播数据传输过程中,一个数据包传输的路径是从源地址路由到目的地址,利用“逐跳”的原理[路由选择]在IP网络中传输。 然而在ip组播环中,数据包的目的地址不是一个,而是一组,形成组地址。所有的信息接收者都加入到一个组内,并且一旦加入之后,流向组地址的数据立即开始向接收者传输,组中的所有成员都能接收到数据包。组播组中的成员是动态的,主机可以在任何时刻加入和离开组播组。 用同一个IP多播地址接收多播数据包的所有主机构成了一个主机组,也称为多播组。一个多播组的成员是随时变动的,一台主机可以随时加入或离开多播组,多播组成员的数目和所在的地理位置也不受限制,一台主机也可以属于几个多播组。此外,不属于某一个多播组的主机也可以向该多播组发送数据包。 组播地址 组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有

Generating Code using Maven - Swagger to Java

Generating Code using Maven - Swagger to Java

In this article, we will talk about generating Java code from Swagger files, which are essentially API specification files for a Web Service. Below video discusses this with the demo. Open API In our previous article, we talked about SOAP services. The challenge with SOAP services is that they tend to be heavy because of XML data usage, and there is a very tight coupling between the client and server. With time, REST Web Services have become the de-facto standard for Web Services, because of their extensibility. REST APIs are documented using the Open API specifications. Open API is a specification for machine-readable interface files for describing, producing, consuming and visualizing RESTful Web Services. These were earlier called swagger specifications when they were developed by [SmartBear Software]. Because of a standard specification, APIs created with this have a common structure and it allows to build tooling around the APIs to cut down on the amount of boilerplate code. Let’s see an example Swagger API. Petstore Swagger API Petstore API is the example Swagger API hosted at swagger.io. The API allows you to manage pets in a store. The API can be viewed in the Swagger UI, which gives a very detailed view of the API, the available operations, the request parameters, headers, authorization, response, all of it. It becomes a handy document for reference as well. Swagger-Codegen Since, Swagger API has well-defined structure, it can be used to generate Java classes for Rest API service and get the API integration going in no time. Swagger Codegen is designed for exact same purpose. Its comes as a standalone binary as well as Maven plugin, to generate the code, and that is what we will use for the Petstore API demo. Project The initial project used in this article is available here. Here are the contents of the Project -> tree . . ├── pom.xml └── src ├── main │   ├── java │   └── resources └── test ├── java

mysql删除数据后释放磁盘空间

mysql删除数据后释放磁盘空间

drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM ; truncate table table_name立刻释放磁盘空间 ,不管是 Innodb和MyISAM; delete from table_name 删除表的全部数据,对于MyISAM 会立刻释放磁盘空间 ,而InnoDB 不会释放磁盘空间; delete from table_name where xx 带条件的删除, 不管是innodb还是MyISAM都不会释放磁盘空间; delete操作后使用optimize table table_name 释放磁盘空间,优化表期间会锁定表,所以要在空闲时段执行optimize table ,测试十几个G数据的表执行optimize table 大概20多分钟。 注:delete删除数据的时候,mysql并没有把数据文件删除,而是将数据文件的标识位删除,没有整理文件,因此不会彻底释放空间。被删除的数据将会被保存在一个链接清单中,当有新数据写入的时候,mysql会利用这些已删除的空间再写入。即,删除操作会带来一些数据碎片,正是这些碎片在占用硬盘空间。 OPTIMIZE TABLE命令优化表,该命令会重新利用未使用的空间,并整理数据文件的碎片;该命令将会整理表数据和相关的索引数据的物理存储空间,用来减少占用的磁盘空间,并提高访问表时候的IO性能;但是具体对表产生的影响是依赖于表使用的存储引擎的。该命令对视图无效。 使用optimize table table_name出现Table does not support optimize, doing recreate + analyze instead 的解决办法: innodb的数据库不支持optimize,可以用 ALTER TABLE table.name ENGINE='InnoDB';对旧表以复制的方式新建一个新表,然后删除旧表。操作前最好备份表。 重新启动mysql ,在启动的时候指定–skip-new或者–safe-mode选项来支持optimize功能 再执行optimize table table_name >/usr/local/mysql/bin/mysqladmin -uroot -p shutdown --停止mysql >/usr/local/mysql/bin/mysqld --skip-new & --启动mysql >mysql -uroot -p --在服务器上连接mysql mysql>use db_name; 删除数据并执行了optimize table释放了磁盘空间;optimize命令优化表 不要频繁操作,另外还发现执行optimize命令 Innodb 引擎的数据库下ibtmp1 文件由原来的几个Gy优化成12M了。 但如果数据每天都大量插入,删除数据后不执行optimize table, insert 数据的时候会占用已经删除那部分数据的空间,数据文件所占用的磁盘空间短时间并不会增长,所以要减少数据文件占用磁盘空间,可以对表进行压缩。 作者:扛着煤气去救火 链接:https://www.jianshu.com/p/ebe6ac68099a 来源:简

Python HTTP 库:requests 快速入门

Python HTTP 库:requests 快速入门

2013 年我接触 Python 的时候,就听闻 Python 的网络编程能力十分强大。因此,在熟悉 Python 的基本语法之后,我就和几个小伙伴一起合作,试着用 Python 的 urllib 和 urllib2 库构建了一个百度贴吧 Python 客户端。 然而,使用的过程中,我发现两个标准库的语法并不自然,甚至可以说十分反人类——用着很难受。又有,我平时使用 Python 甚少涉及到网络编程的内容。因此,Python 的网络编程就被我放下了,直到我认识了 requests 库。 初识 requests requests 库的宣言是 HTTP for Humans (给人用的 HTTP 库) 我们首先来验证一下。 在网络编程中,最最基本的任务包含: 发送请求 登录 获取数据 解析数据 反序列化打印内容 我们以 GitHub 为例,先看一下使用 urllib2 要怎么做。为了把事情弄简单点,我们假设实现已经知道,GET 请求 https://api.github.com/ 返回的内容是个 JSON 格式的数据(实际上通过 content-type 也能判断)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import urllib2 import json gh_url = 'https://api.github.com' cs_user = 'user' cs_psw = 'password' req = urllib2.Request(gh_url) password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() password_manager.add_password(None, gh_url, cs_user, cs_psw) auth_manager = urllib2.HTTPBasicAuthHandler(password_manager) opener = urllib2.build_opener(auth_manager) urllib2.install_opener(opener) handler = urllib2.urlopen(req) if handler.getcode() == requests.codes.ok: text = handler.read() d_text = json.loads(text) for k, v in d_text.items(): print k, v 如果运行正确,那么代码应该返回: 1 2 3 4 5 6 7 issues_url https://api.github.com/issues current_user_repositories_url https://api.github.com/user/repos{?type,page,per_page,sort} rate_limit_url https://api.github.com/rate_limit repository_url https://api.github.com/repos/{owner}/{repo} ... user_repositories_url https://api.github.com/users/{user}/repos{?type,page,per_page,sort} team_url https://api.github.com/teams 同样的效果,用 requests 库则有如下代码: 1 2 3 4 5 6 7 8 9 10 11 import requests cs_url = 'https://api.github.com' cs_user = 'user' cs_psw = 'password' r = requests.get(cs_u

联系我们

联系电话

4000-640-466

联系邮箱

service@f-li.cn

办公地址

上海黄浦区外滩源1号

谢谢,您的信息已成功发送。
请填写信息。