精华内容
下载资源
问答
  • make grade
  • Linux内核学习笔记(八)Page Cache与Page回写

    万次阅读 多人点赞 2018-06-02 23:38:19
    此外,还要确保在page cache中的数据更改时能够被同步到磁盘上,后者被称为page回写(page writeback)。一个inode对应一个page cache对象,一个page cache对象包含多个物理page。 对磁盘的数据进行缓存从而提高...

    你也可以通过我的独立博客 —— www.huliujia.com 获取本篇文章

    综述

    Page cache是通过将磁盘中的数据缓存到内存中,从而减少磁盘I/O操作,从而提高性能。此外,还要确保在page cache中的数据更改时能够被同步到磁盘上,后者被称为page回写(page writeback)。一个inode对应一个page cache对象,一个page cache对象包含多个物理page。

    对磁盘的数据进行缓存从而提高性能主要是基于两个因素:第一,磁盘访问的速度比内存慢好几个数量级(毫秒和纳秒的差距)。第二是被访问过的数据,有很大概率会被再次访问。

    Page Cache

    Page cache由内存中的物理page组成,其内容对应磁盘上的block。page cache的大小是动态变化的,可以扩大,也可以在内存不足时缩小。cache缓存的存储设备被称为后备存储(backing store),注意我们在block I/O一文中提到的:一个page通常包含多个block,这些block不一定是连续的。

    读Cache

    当内核发起一个读请求时(例如进程发起read()请求),首先会检查请求的数据是否缓存到了page cache中,如果有,那么直接从内存中读取,不需要访问磁盘,这被称为cache命中(cache hit)。如果cache中没有请求的数据,即cache未命中(cache miss),就必须从磁盘中读取数据。然后内核将读取的数据缓存到cache中,这样后续的读请求就可以命中cache了。page可以只缓存一个文件部分的内容,不需要把整个文件都缓存进来。

    写Cache

    当内核发起一个写请求时(例如进程发起write()请求),同样是直接往cache中写入,后备存储中的内容不会直接更新。内核会将被写入的page标记为dirty,并将其加入dirty list中。内核会周期性地将dirty list中的page写回到磁盘上,从而使磁盘上的数据和内存中缓存的数据一致。

    Cache回收

    Page cache的另一个重要工作是释放page,从而释放内存空间。cache回收的任务是选择合适的page释放,并且如果page是dirty的,需要将page写回到磁盘中再释放。理想的做法是释放距离下次访问时间最久的page,但是很明显,这是不现实的。下面先介绍LRU算法,然后介绍基于LRU改进的Two-List策略,后者是Linux使用的策略。

    LRU算法

    LRU(least rencently used)算法是选择最近一次访问时间最靠前的page,即干掉最近没被光顾过的page。原始LRU算法存在的问题是,有些文件只会被访问一次,但是按照LRU的算法,即使这些文件以后再也不会被访问了,但是如果它们是刚刚被访问的,就不会被选中。

    Two-List策略

    Two-List策略维护了两个list,active list 和 inactive list。在active list上的page被认为是hot的,不能释放。只有inactive list上的page可以被释放的。首次缓存的数据的page会被加入到inactive list中,已经在inactive list中的page如果再次被访问,就会移入active list中。两个链表都使用了伪LRU算法维护,新的page从尾部加入,移除时从头部移除,就像队列一样。如果active list中page的数量远大于inactive list,那么active list头部的页面会被移入inactive list中,从而位置两个表的平衡。

    Page Cache在Linux中的具体实现

    address_space结构

    内核使用address_space结构来表示一个page cache,address_space这个名字起得很糟糕,叫page_ache_entity可能更合适。下面是address_space的定义

    struct address_space {
        struct inode            *host;              /* owning inode */
        struct radix_tree_root  page_tree;          /* radix tree of all pages */
        spinlock_t              tree_lock;          /* page_tree lock */
        unsigned int            i_mmap_writable;    /* VM_SHARED ma count */
        struct prio_tree_root   i_mmap;             /* list of all mappings */
        struct list_head        i_mmap_nonlinear;   /* VM_NONLINEAR ma list */
        spinlock_t              i_mmap_lock;        /* i_mmap lock */
        atomic_t                truncate_count;     /* truncate re count */
        unsigned long           nrpages;            /* total number of pages */
        pgoff_t                 writeback_index;    /* writeback start offset */
        struct address_space_operations *a_ops;     /* operations table */
        unsigned                long flags;         /* gfp_mask and error flags */
        struct backing_dev_info *backing_dev_info;  /* read-ahead information */
        spinlock_t              private_lock;       /* private lock */
        struct list_head        private_list;       /* private list */
        struct address_space    *assoc_mapping;     /* associated buffers */
    };
    

    其中 host域指向对应的inode对象,host有可能为NULL,这意味着这个address_space不是和一个文件关联,而是和swap area相关,swap是Linux中将匿名内存(比如进程的堆、栈等,没有一个文件作为back store)置换到swap area(比如swap分区)从而释放物理内存的一种机制。page_tree保存了该page cache中所有的page,使用基数树(radix Tree)来存储。i_mmap是保存了所有映射到当前page cache(物理的)的虚拟内存区域(VMA)。nrpages是当前address_space中page的数量。

    address_space操作函数

    address_space中的a_ops域指向操作函数表(struct address_space_operations),每个后备存储都要实现这个函数表,比如ext3文件系统在fs/ext3/inode.c中实现了这个函数表。

    内核使用函数表中的函数管理page cache,其中最重要的两个函数是readpage() 和writepage()

    readpage()函数

    readpage()首先会调用find_get_page(mapping, index)在page cache中寻找请求的数据,mapping是要寻找的page cache对象,即address_space对象,index是要读取的数据在文件中的偏移量。如果请求的数据不在该page cache中,那么内核就会创建一个新的page加入page cache中,并将要请求的磁盘数据缓存到该page中,同时将page返回给调用者。

    writepage() 函数

    对于文件映射(host指向一个inode对象),page每次修改后都会调用SetPageDirty(page)将page标识为dirty。(个人理解swap映射的page不需要dirty,是因为不需要考虑断电丢失数据的问题,因为内存的数据断电时默认就是会失去的)内核首先在指定的address_space寻找目标page,如果没有,就分配一个page并加入到page cache中,然后内核发起一个写请求将数据从用户空间拷入内核空间,最后将数据写入磁盘中。(对从用户空间拷贝到内核空间不是很理解,后期会重点学习Linux读、写文件的详细过程然后写一篇详细的blog介绍)

    Buffer Cache

    在Block I/O的文章中提到用于表示内存到磁盘映射的buffer_head结构,每个buffer-block映射都有一个buffer_head结构,buffer_head中的b_assoc_map指向了address_space。在Linux2.4中,buffer cache和 page cache之间是独立的,前者使用老版本的buffer_head进行存储,这导致了一个磁盘block可能在两个cache中同时存在,造成了内存的浪费。2.6内核中将两者合并到了一起,使buffer_head只存储buffer-block的映射信息,不再存储block的内容。这样保证一个磁盘block在内存中只会有一个副本,减少了内存浪费。

    Flusher线程群(Flusher Threads)

    Page cache推迟了文件写入后备存储的时间,但是dirty page最终还是要被写回磁盘的。

    内核在下面三种情况下会进行会将dirty page写回磁盘:

    • 用户进程调用sync() 和 fsync()系统调用
    • 空闲内存低于特定的阈值(threshold)
    • Dirty数据在内存中驻留的时间超过一个特定的阈值

    线程群的特点是让一个线程负责一个存储设备(比如一个磁盘驱动器),多少个存储设备就用多少个线程。这样可以避免阻塞或者竞争的情况,提高效率。当空闲内存低于阈值时,内核就会调用wakeup_flusher_threads()来唤醒一个或者多个flusher线程,将数据写回磁盘。为了避免dirty数据在内存中驻留过长时间(避免在系统崩溃时丢失过多数据),内核会定期唤醒一个flusher线程,将驻留时间过长的dirty数据写回磁盘。

    参考资料

    《Linux Kernel Development 3rd Edition》
    《Understanding The Linux Kernel 3rd Edition》

    展开全文
  • 出现这样的原因主要是对数据库中查出的集合进行了逻辑判断,total的数量显示与size相同... PageHelper.startPage(page, limit); List<User> allUserList = userService.getAllUserList(name); //新建存储集合...

    出现这样的原因主要是对数据库中查出的集合进行了逻辑判断,total的数量显示与size相同,而不是总条数

            //开启分页
            PageHelper.startPage(page, limit);
            List<User> allUserList = userService.getAllUserList(name);
            //新建存储集合
            List<User> allUserListStatus = new ArrayList<>();
            //判定用户状态,status的状态,数值1为正常状态用户,数值2为禁用状态用户
            for (User user : allUserList) {
                Integer status = user.getStatus();
                if(status==1){
                    if(roleId!=-1){
                        Integer roleIdUser = user.getUserRole().getRoleId();
                        if(roleId.equals(roleIdUser)){
                            allUserListStatus.add(user);
                        }
                    }else{
                        allUserListStatus.add(user);
                    }
    
                }
    
            }
    
            PageInfo<User> pageInfo = new PageInfo<>(allUserList);
            pageInfo.setList(allUserListStatus);
            return ResultUtil.ok(pageInfo);
    

    pageInfo.setList(allUserListStatus);
    这个构造方法是重置pageinfo的pojo对象的list属性,只赋值我们想要的size数量的集合

    展开全文
  • Python+Selenium-driver.page_source获取页面源码

    万次阅读 热门讨论 2021-03-19 17:33:14
    driver.page_source selenium的page_source方法可以获取到页面源码 跟爬虫有点相似,获取到页面资源,提取出我们需要的信息 案例 以煎蛋网为例,获取首页的全部title(获取页面源码 – 使用re正则提取需要的title) ...

    driver.page_source

    selenium的page_source方法可以获取到页面源码

    跟爬虫有点相似,获取到页面资源,提取出我们需要的信息
    案例
    以煎蛋网为例,获取首页的全部title(获取页面源码 – 使用re正则提取需要的title)

    代码

    在这里插入图片描述

    祝大家学习python顺利!

    展开全文
  • JS错误:Mixed Content: The page at ‘https://XXX’ was loaded over HTTPS, but requested an insecure 1、环境 Tomcat Nginx 【走https 通道】 框架形式是以 iframe 作为支撑的 2、问题 主体框架可以正常加载, ...

    JS错误:Mixed Content: The page at ‘https://XXX’ was loaded over HTTPS, but requested an insecure


    如果觉得本文对你有帮助,可以一键三连支持,谢谢

    相关阅读

    Related Reading

    展开全文
  • 手动PageInfo分页

    万次阅读 2020-04-15 15:45:09
    项目中有时候遇到list多种来源,不能使用PageInfo在查询数据库时分页,需要查询全部之后,手动分页。 //手动分页的分割起始下标 Integer fromIndex = 0; //手动分页的分割结尾下标 Integer toIndex = 0; ...
  • 1、pageoffice打开后每次变成系统的登录页面 2、有的电脑上打开显示4页,个别电脑打开该文件显示5页 3、打开word报告,报jQuery未定义错误,需要升级pageoffice版本 4、您的Office软件不支持这个命令,或者这个命令...
  • struct page

    千次阅读 2017-03-27 19:44:19
    struct page是内存管理中第三个重要的数据结构,它代表系统内存的最小单位。  其数据结构如下所示:struct page { /* First double word block */ unsigned long flags; /* Atomic flags, some possibly * ...
  • nginx error_page 使用

    万次阅读 2019-01-09 11:07:34
    接触到了error_page ,这里记录一下 1. error_page语法 语法: error_page code [ code... ] [ = | =answer-code ] uri | @named_location 默认值: no 使用字段: http, server, location, location 中...
  • nginx使用pagespeed

    万次阅读 2018-12-26 17:26:15
    在已有的源码安装的nginx添加page speed模块 下载模块 cd /usr/local/nginx wget https://github.com/pagespeed/ngx_pagespeed/archive/v1.13.35.2-stable.zip 解压 unzip v1.13.35.2-stable.zip 下载psol优化库 cd ...
  • PageInfo介绍及使用

    万次阅读 2018-11-21 10:20:25
    PageInfo介绍及使用1.MyBatis分页插件-PageHelper的配置与应用2.参考封装PageInfo类3.PageInfo属性表 下载PageInfo文档 1.MyBatis分页插件-PageHelper的配置与应用 pom.xml 引入依赖: &lt;!-- pagehelper :...
  • pageoffice使用笔记

    万次阅读 2020-04-16 19:17:21
    文章目录springboot项目集成...springboot项目集成pageoffice 在项目src目录下新建lib文件夹,将jar包引入。 pom文件配置依赖 <dependency> <groupId>com.zhuozhengsoft</groupId> <...
  • PageHelper 分页插件,学到的写法是得到Page 对象后再转成PageInfo 对象,但Page 是ArrayList 的子类,里面包含了数据列表和分页信息,为什么不能直接用Page 对象做分页呢?问题只是如何在页面取出Page 中数据。经过...
  • page = Page() ''' 中间是一些数据 ''' page.add(line)#通过add将多张line page.render("page_name")#通过render这个函数修改名字 ########################################### 报错...
  • Spring Boot JPA分页 PageRequest.of代替过时的PageRequest方法 该篇博客记录了关于Spring Data JPA之 new PageRequest遇到的问题 最近在学习Spring Data Jpa数据持久层这一块知识的时候,在编些dao接口的单元测试...
  • 我在利用PageHelper.startPage(page, rows)做分页时,得到的total始终为0,满足不了工作要求.网上没搜到解决方案,自己调试了好久,才发现,顺序写错了。下面分享一下我工作中在用PageHelper时,遇到的问题,以及...
  • PageObject思想

    千次阅读 2019-05-27 13:54:24
    PageObject 见名思意,就是页面对象。说白就是把页面元素定位和页面元素操作分开。PageObject在实战过程中我们回对脚本实现进行分层。通常做法是分三层: 对象库层 逻辑层 业务层 对象层用于存放我们的页面元素和...
  • list转page分页

    千次阅读 2019-09-03 14:37:33
    private List listToPage(int currentPage, int rows, List list) { currentPage = (currentPage - 1) * rows; //每页的起始索引 Integer sum = list.size(); //记录总数 if (currentPage + rows &g...
  • selenium自动化测试PageObject

    万次阅读 2020-10-06 10:57:59
    PageObject模式 做法 以页⾯为单位独⽴建模 隐藏实现细节 本质是⾯向接⼜编程 优点 减少重复find click样板代码 易读性提⾼ 页⾯修改不影响测试⽤例 Page Object Model的基本原则 ⽅法意义 ⽤公共⽅法代表UI...
  • pagehelper,pageinfo用法

    万次阅读 热门讨论 2018-09-18 14:59:26
    pagehelper,从pageinfo 中取到的total不正确的处理。 最近在使用pagehelper时遇到一些问题。2个类似的查询都用的PageHelper.startPage进行分页,A方法pageinfo中取出来的total,pages是正确的,B方法取出来的确...
  • a padding to disable MSIE and Chrome friendly error page错误解决方法
  • 通过PAGE生成python GUI界面(用PAGE拖出需要的GUI界面)

    万次阅读 热门讨论 2018-07-15 22:39:33
    注:当前我的使用环境为windows10 64bit/python v3.6/PAGE v4.14/Tcl v8.6.7.0当前我定义一个目标,最终需要生成一个登录界面的GUI代码,如下:安装好各软件后,就可以运行PAGE来像VB一样所见即可得的拖出我们需要的...
  • PageHelper.startPage和new PageInfo(list)的一些探索和思考

    千次阅读 多人点赞 2019-08-13 22:13:12
    平常我们使用分页插件的时候,都是很机械的... PageHelper.startPage(1, 10); Example example = new Example(Employee.class); example.createCriteria().andEqualTo("employeeSex", "男"); List<Employee&g...
  • PageOffice for Java (免费破解版)文档控件(官网版本)

    千次下载 热门讨论 2014-03-08 10:13:34
    PageOffice实现了在线编辑保存Word、Excel、PPT、WPS等Office文档的基本功能,对于简单的在线Office办公、追踪Word修订痕迹、全文检索的实现已经绰绰有余。 PageOffice是市场上唯一一款能够同时支持IE、谷歌Chrome...
  • 当前pyecharts的版本为1.9.0。 概述 pyecharts/charts/composite_charts/包中的四个模块分别定义了组合图表类,其中pyecharts/charts/...Page类的签名为class Page(page_title: str = "Awesome-pyecharts", js_
  • java分页Page

    万次阅读 2018-08-31 11:25:48
    public class Page implements Serializable { private int currentPageNum;//当前页 private int pageSize=5;//每页显示的条数 private int totalRecords;//总记录条数 private int startIndex;//查询的开始记录...
  • PageOffice 安装使用说明

    万次阅读 2019-06-15 00:13:35
    1. 访问pageoffice官网,下载pageoffice开发包。拷 贝 Samples4 文 件 夹 到 Tomcat 的 Webapps 目 录 下 , 访 问 : http://localhost:8080/Samples4/index.html 2. 如果新建网站或集成到您现有的网站里: 1). ...
  • 什么是Page Objects(PageObjects 设计模式)

    万次阅读 2014-05-07 15:34:55
    什么是Page Objects(翻译为:页面对象?) 写在最前面,感谢超爷的这个文档。  2012-10-17你完成的,我到了14年的5月才回过神来整理这部分知识。 部分内容来自:...
  • 一、需求:实现Springboot中MyBatisplus使用IPage和Page分页 二、技术:MyBatisplus的IPage和Page 三、实现 1、代码结构 2、代码详情 (1)Controller package com.xkcoding.rbac.security.controller; ...
  • iview page分页组件的集成

    万次阅读 多人点赞 2017-12-23 11:40:17
    iview page分页组件的集成  今天给大家分享一下iview page分页组件与iview table表格的集成,主要是针对前端集成,整个前端采用vue渲染,首先我们查看一下iview page分页组件https://www.iviewui.com/components/page...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,951,375
精华内容 780,550
关键字:

page