7 php 内存泄漏_PHP 内存泄漏分析定位

引用前言

本文开始撰写时我负责的项目需要用php开发一个通过 Socket 与服务端建立长连接后持续实时上报数据的常驻进程程序,在程序业务功能开发联调完毕后实际运行发送大量数据后发现内存增长非常迅速,在很短的时间内达到了 php 默认可用内存上限 128M ,并报错:

Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes)

我第一反应是内存泄露了,但是不知道在哪。第二反应是无用的变量应该用完就 unset 掉,修改完毕后问题依旧。经过了几番周折终于解决了问题。就决定好好把类似情况整理一下,遂有此文,与诸君共勉。

观察 PHP 程序内存使用情况

php提提供了两个方法来获取当前程序的内存使用情况。

memorygetusage(),这个函数的作用是获取目前PHP脚本所用的内存大小。

memorygetpeak_usage(),这个函数的作用返回当前脚本到目前位置所占用的内存峰值,这样就可能获取到目前的脚本的内存需求情况。int memory_get_usage ([ bool $real_usage = false ] )

int memory_get_peak_usage ([ bool $real_usage = false ] )

函数默认得到的是调用emalloc()占用的内存,如果设置参数为TRUE,则得到的是实际程序向系统申请的内存。因为 PHP 有自己的内存管理机制,所以有时候尽管内部已经释放了内存但并没有还给系统。

linux 系统文件 /proc/{$pid}/status 会记录某个进程的运行状态,里面的 VmRSS 字段记录了该进程使用的常驻物理内存(Residence),这个就是该进程实际占用的物理内存了,用这个数据比较靠谱,在程序里面提取这个值也很容易

场景一:程序操作数据过大

情景还原:一次性读取超过php可用内存上限的数据导致内存耗尽

ini_set('memory_limit', '128M');

$string = str_pad('1', 128 * 1024 * 1024);

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 134217729 bytes) in /Users/zouyi/php-oom/bigfile.php on line 3

这是告诉我们程序运行时试图分配新内存时由于达到了PHP允许分配的内存上限而抛出致命错误,无法继续执行了,在 java 开发中一般称之为 OOM ( Out Of Memory ) 。

PHP 配置内存上限是在php.ini中设置memory_limit,PHP 5.2 以前这个默认值是8M,PHP 5.2 的默认值是16M,在这之后的版本默认值都是128M。

问题现象:特定数据处理时可复现,做任何 IO 操作都有可能遇到此类问题,比如:一次 mysql 查询返回大量数据、一次把大文件读取进程序等。

解决方法:

能用钱解决的问题都不是问题,如果程序要读大文件的机会不是很多,且上限可预期,那么通过ini_set('memory_limit', '1G');来设置一个更大的值或者memory_limit=-1。内存管够的话让程序一直跑也可以。

如果程序需要考虑在小内存机器上也能正常使用,那就需要优化程序了。如下,代码复杂了很多。<?php

//php7 以下版本通过 composer 引入 paragonie/random_compat ,为了方便来生成一个随机名称的临时文件

require "vendor/autoload.php";

ini_set('memory_limit', '128M');

//生成临时文件存放大字符串

$fileName = 'tmp'.bin2hex(random_bytes(5)).'.txt';

touch($fileName);

for ( $i = 0; $i < 128; $i++ ) {

$string = str_pad('1', 1 * 1024 * 1024);

file_put_contents($fileName, $string, FILE_APPEND);

}

$handle = fopen($fileName, "r");

for ( $i = 0; $i <= filesize($fileName) / 1 * 1024 * 1024; $i++ )

{

//do something

$string = fread($handle, 1 * 1024 * 1024);

}

fclose($handle);

unlink($fileName);

场景二:程序操作大数据时产生拷贝

情景还原:执行过程中对大变量进行了复制,导致内存不够用。

ini_set("memory_limit",'1M');

$string = str_pad('1', 1* 750 *1024);

$string2 = $string;

$string2 .= '1';

Fatal error: Allowed memory size of 1048576 bytes exhausted (tried to allocate 768001 bytes) in /Users/zouyi/php-oom/unset.php on line 8

Call Stack:

0.0004 235440 1. {main}() /Users/zouyi/php-oom/unset.php:0

zend_mm_heap corrupted

问题现象:局部代码执行过程中占用内存翻倍。

问题分析:

php 是写时复制(Copy On Write),也就是说,当新变量被赋值时内存不发生变化,直到新变量的内容被操作时才会产生复制。

解决方法:

及早释放无用变量,或者以引用的形式操作原始数据。

ini_set("memory_limit",'1M');

$string = str_pad('1', 1* 750 *1024);

$string2 = $string;

unset($string);

$string2 .= '1';

ini_set("memory_limit",'1M');

$string = str_pad('1', 1* 750 *1024);

$string2 = &$string;

$string2 .= '1';

unset($string2, $string);

场景三:配置不合理系统资源耗尽

情景还原:因配置不合理导致内存不够用,2G 内存机器上设置最大可以启动 100 个 php-fpm 子进程,但实际启动了 50 个 php-fpm 子进程后无法再启动更多进程

问题现象:线上业务请求量小的时候不出现问题,请求量一旦很大后部分请求就会执行失败

问题分析:

一般为了安全方面考虑, php 限制表单请求的最大可提交的数量及大小等参数,post_max_size、max_file_uploads、upload_max_filesize、max_input_vars、max_input_nesting_level。 假设带宽足够,用户频繁的提交post_max_size = 8M数据到服务端,nginx 转发给 php-fpm 处理,那么每个 php-fpm 子进程除了自身占用的内存外,即使什么都不做也有可能多占用 8M 内存。

解决方法:

合理设置post_max_size、max_file_uploads、upload_max_filesize、max_input_vars、max_input_nesting_level等参数并调优 php-fpm 相关参数。

$ php -i |grep memory

memory_limit => 1024M => 1024M //php脚本执行最大可使用内存

$php -i |grep max

max_execution_time => 0 => 0 //最大执行时间,脚本默认为0不限制,web请求默认30s

max_file_uploads => 20 => 20 //一个表单里最大上传文件数量

max_input_nesting_level => 64 => 64 //一个表单里数据最大数组深度层数

max_input_time => -1 => -1 //php从接收请求开始处理数据后的超时时间

max_input_vars => 1000 => 1000 //一个表单(包括get、post、cookie的所有数据)最多提交1000个字段

post_max_size => 8M => 8M //一次post请求最多提交8M数据

upload_max_filesize => 2M => 2M //一个可上传的文件最大不超过2M

如果上传设置不合理那么出现大量内存被占用的情况也不奇怪,比如有些内网场景下需要 post 超大字符串post_max_size=200M,那么当从表单提交了 200M 数据到服务端, php 就会分配 200M 内存给这条数据,直到请求处理完毕释放内存。

pm = dynamic //仅dynamic模式下以下参数生效

pm.max_children = 10 //最大子进程数

pm.start_servers = 3 //启动时启动子进程数

pm.min_spare_servers = 2 //最小空闲进程数,不够了启动更多进程

pm.max_spare_servers = 5 //最大空闲进程数,超过了结束一些进程

pm.max_requests = 500 //最大请求数,注意这个参数是一个php-fpm如果处理了500个请求后会自己重启一下,可以避免一些三方扩展的内存泄露问题

一个 php-fpm 进程按 30MB 内存算,50 个 php-fpm 进程就需要 1500MB 内存,这里需要简单估算一下在负载最重的情况下所有 php-fpm 进程都启动后是否会把系统内存耗尽。

$ulimit -a

-t: cpu time (seconds) unlimited

-f: file size (blocks) unlimited

-d: data seg size (kbytes) unlimited

-s: stack size (kbytes) 8192

-c: core file size (blocks) 0

-v: address space (kbytes) unlimited

-l: locked-in-memory size (kbytes) unlimited

-u: processes 1024

-n: file descriptors 1024

这是我本地mac os的配置,文件描述符的设置是比较小的,一般生产环境配置要大得多。

场景四:无用的数据未及时释放

情景还原:这种问题从程序逻辑上不是问题,但是无用的数据大量占用内存导致资源不够用,应该有针对性的做代码优化。

Laravel开发中用于监听数据库操作时有如下代码:

DB::listen(function ($query) {

// $query->sql

// $query->bindings

// $query->time

});

启用数据库监听后,每当有 SQL 执行时会 new 一个 QueryExecuted 对象并传入匿名函数以便后续操作,对于执行完毕就结束进程释放资源的php程序来说没有什么问题,而如果是一个常驻进程的程序,程序每执行一条 SQL 内存中就会增加一个 QueryExecuted 对象,程序不结束内存就会始终增长。

问题现象:程序运行期间内存逐渐增长,程序结束后内存正常释放。

问题分析:

此类问题不易察觉,定位困难,尤其是有些框架封装好的方法,要明确其适用场景。

解决方法:

本例中要通过DB::listen方法获取所有执行的 SQL 语句记录并写入日志,但此方法存在内存泄露问题,在开发环境下无所谓,在生产环境下则应停用,改用其他途径获取执行的 SQL 语句并写日志。

深入了解

1. 名词解释

内存泄漏(Memory Leak):是程序在管理内存分配过程中未能正确的释放不再使用的内存导致资源被大量占用的一种问题。在面向对象编程时,造成内存泄露的原因常常是对象在内存中存储但是运行中的代码却无法访问他。由于产生类似问题的情况很多,所以只能从源码上入手分析定位并解决。

垃圾回收(Garbage Collection,简称GC):是一种自动内存管理的形式,GC程序检查并处理程序中那些已经分配出去但却不再被对象使用的内存。最早的GC是1959年前后John McCarthy发明的,用来简化在Lisp中手动控制内存管理。 PHP的内核中已自带内存管理的功能,一般应用场景下,不易出现内存泄露。

追踪法(Tracing):从某个根对象开始追踪,检查哪些对象可访问,那么其他的(不可访问)就是垃圾。

引用计数法(reference count):每个对象都一个数字用来标示被引用的次数。引用次数为0的可以回收。当对一个对象的引用创建时他的引用计数就会增加,引用销毁时计数减少。引用计数法可以保证对象一旦不被引用时第一时间销毁。但是引用计数有一些缺陷:1.循环引用,2.引用计数需要申请更多内存,3.对速度有影响,4.需要保证原子性,5.不是实时的2. php 内存管理

引用

在 PHP 5.2 以前, PHP 使用引用计数(Reference count)来做资源管理, 当一个 zval 的引用计数为 0 的时候, 它就会被释放. 虽然存在循环引用(Cycle reference), 但这样的设计对于开发 Web 脚本来说, 没什么问题, 因为 Web 脚本的特点和它追求的目标就是执行时间短, 不会长期运行. 对于循环引用造成的资源泄露, 会在请求结束时释放掉. 也就是说, 请求结束时释放资源, 是一种部补救措施( backup ).

然而, 随着 PHP 被越来越多的人使用, 就有很多人在一些后台脚本使用 PHP , 这些脚本的特点是长期运行, 如果存在循环引用, 导致引用计数无法及时释放不用的资源, 则这个脚本最终会内存耗尽退出.

所以在 PHP 5.3 以后, 我们引入了 GC .

—— 摘自鸟哥博客文章《请手动释放你的资源》

在 PHP 5.3 以后引入了同步周期回收算法(Concurrent Cycle Collection)来处理内存泄露问题,代价是对性能有一定影响,不过一般 web 脚本应用程序影响很小。PHP的垃圾回收机制是默认打开的,php.ini 可以设置zend.enable_gc=0来关闭。也能通过分别调用gcenable() 和 gcdisable()函数来打开和关闭垃圾回收机制。

虽然垃圾回收让php开发者在内存管理上无需担心了,但也有极端的反例:php界著名的包管理工具composer曾因加入一行gc_disable();性能得到极大提升。传送门

引用计数基本知识

回收周期(Collecting Cycles)

上面两个链接是php官方手册中的内存管理、GC相关知识讲解,图文并茂,这里不再赘述。

3. php-fpm 内存泄露问题

在一台常见的 nginx + php-fpm 的服务器上:

nginx 服务器 fork 出 n 个子进程(worker), php-fpm 管理器 fork 出 n 个子进程。

当有用户请求, nginx 的一个 worker 接收请求,并将请求抛到 socket 中。

php-fpm 空闲的子进程监听到 socket 中有请求,接收并处理请求。一个 php-fpm 的生命周期大致是这样的:

模块初始化(MINIT)-> 请求初始化(RINIT)-> 请求处理 -> 请求结束(RSHUTDOWN) -> 请求初始化(RINIT)-> 请求处理 -> 请求结束(RSHUTDOWN)……. 请求初始化(RINIT)-> 请求处理 -> 请求结束(RSHUTDOWN)-> 模块关闭(MSHUTDOWN)。

在请求初始化(RINIT)-> 请求处理 -> 请求结束(RSHUTDOWN)这个“请求处理”过程是: php 读取相应的 php 文件,对其进行词法分析,生成 opcode , zend 虚拟机执行 opcode 。

php 在每次请求结束后自动释放内存,有效避免了常见场景下内存泄露的问题,然而实际环境中因某些扩展的内存管理没有做好或者 php 代码中出现循环引用导致未能正常释放不用的资源。

在 php-fpm 配置文件中,将pm.max_requests这个参数设置小一点。这个参数的含义是:一个 php-fpm 子进程最多处理pm.max_requests个用户请求后,就会被销毁。当一个 php-fpm 进程被销毁后,它所占用的所有内存都会被回收。

4. 常驻进程内存泄露问题

Valgrind 包括如下一些工具:

Memcheck。这是 valgrind 应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。

Callgrind。它主要用来检查程序中函数调用过程中出现的问题。

Cachegrind。它主要用来检查程序中缓存使用出现的问题。

Helgrind。它主要用来检查多线程程序中出现的竞争问题。

Massif。它主要用来检查程序中堆栈使用中出现的问题。

Extension。可以利用core提供的功能,自己编写特定的内存调试工具。Memcheck 对调试 C/C++ 程序的内存泄露很有帮助,它的机制是在系统 alloc/free 等函数调用上加计数。 php 程序的内存泄露,是由于一些循环引用,或者 gc 的逻辑错误, valgrind 无法探测,因此需要在检测时需要关闭 php 自带的内存管理。

$ export USE_ZEND_ALLOC=0 # 设置环境变量关闭内存管理

$ valgrind --tool=memcheck --num-callers=30 --log-file=php.log /Users/zouyi/Downloads/php-5.6.31/sapi/cli/php leak.php

通过命令行执行 valgrind 分析可能有内存泄露的文件

引用

==12075== Memcheck, a memory error detector

==12075== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.

==12075== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info

==12075== Command: /Users/zouyi/Downloads/php-5.6.31/sapi/cli/php leak.php

==12075== Parent PID: 42043

==12075==

==12075== Syscall param msg->desc.port.name points to uninitialised byte(s)

==12075==    at 0x10121F34A: mach_msg_trap (in /usr/lib/system/libsystem_kernel.dylib)

==12075==    by 0x10121E796: mach_msg (in /usr/lib/system/libsystem_kernel.dylib)

==12075==    by 0x101218485: task_set_special_port (in /usr/lib/system/libsystem_kernel.dylib)

==12075==    by 0x1013B410E: _os_trace_create_debug_control_port (in /usr/lib/system/libsystem_trace.dylib)

==12075==    by 0x1013B4458: _libtrace_init (in /usr/lib/system/libsystem_trace.dylib)

==12075==    by 0x100DF09DF: libSystem_initializer (in /usr/lib/libSystem.B.dylib)

==12075==    by 0x100C37A1A: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)

==12075==    by 0x100C37C1D: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)

==12075==    by 0x100C334A9: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)

==12075==    by 0x100C33440: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)

==12075==    by 0x100C32523: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)

==12075==    by 0x100C325B8: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)

==12075==    by 0x100C24433: dyld::initializeMainExecutable() (in /usr/lib/dyld)

==12075==    by 0x100C288C5: dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) (in /usr/lib/dyld)

==12075==    by 0x100C23248: dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) (in /usr/lib/dyld)

==12075==    by 0x100C23035: _dyld_start (in /usr/lib/dyld)

==12075==    by 0x1: ???

==12075==    by 0x1054AC862: ???

==12075==    by 0x1054AC891: ???

==12075==  Address 0x1054aa98c is on thread 1's stack

==12075==  in frame #2, created by task_set_special_port (???:)

==12075==

--12075-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option

--12075-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)

--12075-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)

==12075==

==12075== HEAP SUMMARY:

==12075==     in use at exit: 125,805 bytes in 185 blocks

==12075==   total heap usage: 14,686 allocs, 14,501 frees, 3,261,322 bytes allocated

==12075==

==12075== LEAK SUMMARY:

==12075==    definitely lost: 3 bytes in 1 blocks

==12075==    indirectly lost: 0 bytes in 0 blocks

==12075==      possibly lost: 72 bytes in 3 blocks

==12075==    still reachable: 107,582 bytes in 23 blocks

==12075==         suppressed: 18,148 bytes in 158 blocks

==12075== Rerun with --leak-check=full to see details of leaked memory

==12075==

==12075== For counts of detected and suppressed errors, rerun with: -v

==12075== Use --track-origins=yes to see where uninitialised values come from

==12075== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1)

引用

definitely lost: 肯定内存泄露

indirectly lost: 非直接内存泄露

possibly lost: 可能发生内存泄露

still reachable: 仍然可访问的内存

suppressed: 外部造成的内存泄露

Callgrind 配合 php 扩展 xdebug 输出的 profile 分析日志文件可以分析程序运行期间各个函数调用时占用的内存、 CPU 占用情况。

总结

遇到了内存泄露时先观察是程序本身内存不足还是外部资源导致,然后搞清楚程序运行中用到了哪些资源:写入磁盘日志、连接数据库 SQL 查询、发送 Curl 请求、 Socket 通信等, I/O 操作必然会用到内存,如果这些地方都没有发生明显的内存泄露,检查哪里处理大量数据没有及时释放资源,如果是 php 5.3 以下版本还需考虑循环引用的问题。多了解一些 Linux 下的分析辅助工具,解决问题时可以事半功倍。

最后宣传一下穿云团队今年最新开源的应用透明链路追踪工具 Molten:https://github.com/chuan-yun/Molten。安装好php扩展后就能帮你实时收集程序的 curl,pdo,mysqli,redis,mongodb,memcached 等请求的数据,可以很方便的与 zipkin 集成。

参考资料

http://php.net/manual/zh/features.gc.php

http://www.php-internals.com/book/?p=chapt06/06-07-memory-leaks

http://www.programering.com/a/MDN5UjMwATk.html

https://stackoverflow.com/questions/20458136/using-valgrind-to-debug-a-php-cli-segmentation-fault

http://www.laruence.com/2013/08/14/2899.html

https://mengkang.net/873.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/486041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html5+实现图片自动切换,js图片自动切换效果处理代码

var curIndex0;//时间间隔 单位毫秒var timeInterval1000;var arrnew Array();arr[0]"1.jpg";arr[1]"2.jpg";arr[2]"3.jpg";arr[3]"4.jpg";arr[4]"5.jpg";arr[5]"6.jpg";arr[6]"7.jpg";setInterval(cha…

深度学习已经彻底改变了制造业的质量控制,但还不够深入

Photo-illustration: Neurala来源&#xff1a;IEEE电气电子工程师这是一篇客座文章。这里所表达的观点只是作者的观点&#xff0c;并不代表IEEE Spectrum或IEEE的立场。在2020年&#xff0c;我们看到了深度学习的加速利用&#xff0c;这是所谓的工业4.0革命的一部分&#xff0c…

HTML--标签

基本 <html>…</html> 定义 HTML 文档 <head>…</head> 文档的信息 <meta> HTML 文档的元信息 <title>…</title> 文档的标题 <link> 文档与外部资源的关系 <…

Pycharm简单配置及详细快捷键介绍

Pycharm的配置 修改主题&#xff1a; File-》Setting&#xff1a; Appearance&Behavior->UI Options->Theme: 显示行号&#xff1a; Editor-General-Appearance 选择show line numbers显示行号&#xff1a; 修改字体大小&#xff1a; Editor-Colors&Font-Font&am…

linux 查看vnc端口_VNC常用操作及常见问题解决办法汇总

VNC登录用户缺省是root,但在安装oracle时必须用oracle用户的身份登录,下面我们就以oracle为例说明如何配置VNC,从而可以使用不同的用户登录到主机。 步骤描述如下: 步骤一:修改/etc/sysconfig/vncservers,添加oracle用户,修改后内容如下: VNCSERVERS="1:root 2:ro…

html5+游戏+广告,给html5 游戏添加admob广告挣钱盈利

给html5游戏添加admob广告挣钱盈利经过几年的发展&#xff0c;html5逐渐发展起来&#xff0c;特别是今年以来已经有不少html5游戏作品面世&#xff0c;作为开发者&#xff0c;如何通过html5游戏挣钱还是个问题。这里就先介绍下通过给html5游戏或者html5应用添加广告挣取收入的方…

“重”磅!人造物质量首超全球生物量

图片来源&#xff1a;HUSEYINTUNCER/ ISTOCK来源&#xff1a;科学技术哲学作者&#xff1a;辛雨12月10日&#xff0c;《自然》发表的最新研究显示&#xff0c;建筑、道路、汽车等人造物体的质量现已超过地球上的生物总量&#xff0c;而每周的新增物量相当于地球上近80亿人口的总…

06-图1 列出连通集

06-图1 列出连通集&#xff08;25 分&#xff09;给定一个有N个顶点和E条边的无向图&#xff0c;请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时&#xff0c;假设我们总是从编号最小的顶点出发&#xff0c;按编号递增的顺序访问邻接点。输入格式:输入…

c# 带返回值的action_C#委托的介绍(delegate、Action、Func、predicate)

委托是一个类&#xff0c;它定义了方法的类型&#xff0c;使得可以将方法当作另一个方法的参数来进行传递。事件是一种特殊的委托。1.委托的声明(1). delegatedelegate我们常用到的一种声明Delegate至少0个参数&#xff0c;至多32个参数&#xff0c;可以无返回值&#xff0c;也…

html固定表的属性是什么,css如何固定表头

css如何固定表头实现头部导航栏固定用到的属性是&#xff1a;position:sticky 。粘性定位元素(stickily positioned element)是计算后位置属性为 sticky 的元素。盒位置根据正常流计算(这称为正常流动中的位置)&#xff0c;然后相对于该元素在流中的 flow root(BFC)和 containi…

HTML--注册页面案例

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title></title> </head> <body> <!--表里标签&#xff1a;action:提交的地址 method&#xff1a; get…

如何给网页标题添加icon小图标

今天给大家分享的是如何在网页标题中加入小图标&#xff0c;就像CSDN前面那个红色的C一样。主要介绍两种方法&#xff1a;1.在html文件的head部分添加下面代码&#xff08;注意href的路径&#xff09;。<link rel"icon" type"image/x-icon" href"i…

科技界内卷化如何破

本文转载自李侠科学网博客撰文 | 李侠&#xff08;上海交通大学科学史与科学文化研究院教授&#xff09;众所周知&#xff0c;2020年内卷化成为一个年度热词&#xff0c;它本是美国文化人类学家吉尔茨&#xff08;Clifford Geertz&#xff0c;1926-2006&#xff09;提出的一个概…

android 内存不足 io,[转]分析ANR或者系统内存崩溃的问题

一&#xff1a;什么是ANRANR:Application Not Responding&#xff0c;即应用无响应二&#xff1a;ANR的类型ANR一般有三种类型&#xff1a;1&#xff1a;KeyDispatchTimeout(5 seconds) --主要类型按键或触摸事件在特定时间内无响应2&#xff1a;BroadcastTimeout(10 seconds)B…

golang map 锁_golang 并发安全Map以及分段锁的实现

涉及概念并发安全Map分段锁sync.MapCAS ( Compare And Swap )双检查分断锁type SimpleCache struct {mu sync.RWMutexitems map[interface{}]*simpleItem}在日常开发中&#xff0c; 上述这种数据结构肯定不少见&#xff0c;因为golang的原生map是非并发安全的&#xff0c;所以为…

动态规划--Leetcode63.不同路径二

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为“Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为“Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到右下角将…

IEEE:2021年的机遇、挑战以及关键的科技趋势

来源&#xff1a;笑看国际风云【导读】近日&#xff0c;一直致力于通过推动科技进步以造福全人类、全球最大的专业技术组织IEEE&#xff08;电气电子工程师学会&#xff09;&#xff0c;发布了《IEEE全球CIO、CTO访问调研&#xff1a;2021年的机遇和挑战&#xff0c;以及关键的…

MRTG在Windows平台的安装及使用

MRTG (Multi Router Traffic Grapher)是一款监控网络流量负载的免费软件&#xff0c;目前利用MRTG已经开发出了各式各样的统计系统&#xff1a; 1&#xff0e;系统资源负载统计&#xff0c;例如&#xff1a;磁盘空间、CPU负载、内存用量等等 2&#xff0e;Server流量统计&#…

计算机教室应用计划,计算机教室新学期工作计划

无论是单位还是个人&#xff0c;有了工作计划&#xff0c;工作就有了明确的目标和具体的步骤&#xff0c;就可以协调大家的行动&#xff0c;增强工作的主动性&#xff0c;使工作有条不紊地进行。下面是小编整理的计算机教室新学期工作计划&#xff0c;欢迎大家参考!计算机教室新…

语音识别中强制对齐_一种在线语音文本对齐系统及方法

专利名称&#xff1a;一种在线语音文本对齐系统及方法技术领域&#xff1a;本发明涉及电视字幕显示领域&#xff0c;特别涉及一种在线语音文本对齐系统及方法。背景技术&#xff1a;一个国家电视字幕节目的比例&#xff0c;反应了一个国家的人文水平&#xff0c;反应了社会对残…