关于`IRIS/Caché`进程内存溢出解决方案

news2024/10/6 12:27:14

文章目录

  • 关于`IRIS/Caché`进程内存溢出解决方案
    • 描述
    • 原因
    • 相关系统变量
      • `$ZSTORAGE`
      • `$STORAGE`
    • 什么情况下进程内存会变化?
    • 内存不足原理
    • 解决方案

关于 IRIS/Caché进程内存溢出解决方案

描述

IRIS/Caché中,进程内存溢出错误是指一个进程(例如运行中的作业JOB、应用程序或服务)在执行过程中消耗了超过其分配内存限制的内存资源,导致操作系统无法继续为其提供足够的内存空间。这可能会导致进程崩溃、运行缓慢或产生不稳定的行为。

原因

进程内存溢出错误可能由以下情况引起:

  • 内存泄漏:进程中的代码在使用完内存后未正确释放,导致内存逐渐耗尽,最终导致溢出。

  • 大量数据处理:处理大量数据时,如果未及时释放已使用的内存,可能会导致内存耗尽。

  • 递归调用:递归调用未正确终止或控制,可能导致堆栈溢出,最终影响进程的内存。

IRIS/Caché中,会提示<STORE>错误。

相关系统变量

在讲原理之前需要先了解两个系统变量$STORAGE$ZSTORAGE

$ZSTORAGE

$ZSTORAGE包含进程私有内存的最大内存量(以KB为单位)。

USER>w $zs
262144

可以在Portal中更改最大每进程内存(KB)系统配置设置来更改$ZSTORAGE默认值。默认值为262144KB256M,如下截图:

在这里插入图片描述

$STORAGE

$STORAGE返回可用于当前进程中的变量存储的字节数。 $STORAGE的初始值由$ZSTORAGE的值确定,该值是该进程可用的最大内存量。 $ZSTORAGE值(以千字节为单位)越大,$STORAGE值(以字节为单位)越大。但$ZSTORAGE$STORAGE之间的关系不是绝对的1:1

USER>w $s
268313368
USER>w $s/1024
262024.7734375
USER>w $s/1024/1024
255.8835678100585938

什么情况下进程内存会变化?

  • 使用set命令,进程内存$STORAGE会减少。
ClassMethod Store()
{
	w $s,!
	s name = "yx"
	w $s,!
	s age = 18
	w $s,!
}

注:可观察到减小的数量为8的倍数。也就是说以字节为单位进行递减。

USER>d ##class(M.Store).Store()
268307096
268307088
268307080
  • 重复局部变量不会减小进程内存$STORAGE
ClassMethod Store1()
{
	w $s,!
	s name = "yx"
	w $s,!
	s age = 18
	w $s,!
	s name = "yx"
	w $s,!
	s age = 18
	w $s,!
	w name,!
	w $s,!
	w age,!
	w $s,!
}
USER>d ##class(M.Store).Store1()
268306968
268306960
268306952
268306952
268306952
yx
268306952
18
268306952
  • 局部变量名称大小对进程内存$STORAGE没有影响,并不是说变量名称越长所占内存越多。
ClassMethod Store2()
{
	w $s,!
	s name = "yx"
	w $s,!
	s namenamenamenamenamename = "yx"
	w $s,!
	s namenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamename = "yx"
	w $s,!
}
USER>d ##class(M.Store).Store2()
268306968
268306960
268306952
268306944
  • 局部变量所保存的值影响进程内存$STORAGE
ClassMethod Store3()
{
	w $s,!
	s name = "yx"
	w $s,!
	s name = "yxyxyxyx"
	w $s,!
	s name = "yxyxyxyxyxyxyxyx"
	w $s,!
	s name = "yxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyx"
	w $s,!
}

注:可观察到字符串越长,所占用的内存越多。

USER>d ##class(M.Store).Store3()
268306968
268306960
268306936
268306904
268306840
  • 多维数组会影响进程内存$STORAGE,下标越多占用的内存越多。
ClassMethod Store4()
{
	w $s,!
	s array(1) = 1
	w $s,!
	s array(2) = 2
	w $s,!
	s array(3) = "yxyx"
	w $s,!
	s array(4) = "yxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyx"
	w $s,!
}
USER>d ##class(M.Store).Store4()
268306968
268306896
268306888
268306680
268306552
  • 删除局部变量,多维数组,可以使进程内存$STORAGE增加或恢复。
ClassMethod Store5()
{
	w $s,!
	s name = "yx"
	w $s,!
	s name = "yxyxyxyx"
	w $s,!
	k name
	w "删除局部变量后:" _ $s,!
	
	w $s,!
	s array(1) = 1
	w $s,!
	s array(2) = 2
	w $s,!
	s array(3) = "yxyx"
	w $s,!
	s array(4) = "yxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyx"
	w $s,!
	k array
	w "删除多维数组后:" _ $s,!
}
USER>d ##class(M.Store).Store5()
268306968
268306960
268306936
删除局部变量后:268306968
268306968
268306896
268306888
268306680
268306552
删除多维数组后:268306968
  • 使用NEW命令时,$STORAGE会减少。因为N会增加堆栈级别,也就意味发生堆栈级别改变的命令都会使内存减少。
ClassMethod Store6()
{
	w $s,!
	n
	w $s,!
	n
	w $s,!
	n
	w $s,!
}

注:第一次使用New命令时,减少13336,后续的New命令均减少12228

USER>d ##class(M.Store).Store6()
268306968
268293632
268281344
268269056
  • 块语法IF、ELES、FOR、TRY、CATCH命令不会使用$STORAGE会减少。
ClassMethod Store7()
{
	w $s,!
	if 1 {
		w $s,!
		if 1 {
			w $s,!
		} 
	} else {
		w $s,!
	}
	w $s,!
	
	try {
		w $s,!
	} catch {
		w $s,!
	}
	w $s,!
	
	for {
		w $s,!
		b
	}
}

USER>d ##class(M.Store).Store7()
268288144
268288144
268288144
268288144
268288144
268288144
268288144
 
  b
  ^
<BREAK>zStore7+19^M.Store.1
USER 3f2>
  • $STORAGE值不受设置的进程私有Global、与临时Global影响。
ClassMethod Store8()
{
	w $s,!
	k ^yx
	w $s,!
	k ^||yx
	w $s,!
	s ^yx("name") = "yx"
	w $s,!
	s ^yx("age") = 18
	w $s,!
	s ^||yx("address") = "china"
	w $s,!
	s ^||yx("work") = "码农"
	w $s,!
}
USER>d ##class(M.Store).Store8()
268287376
268287376
268287376
268287376
268287376
268287376
268287376
  • 局部变量字符串长度与进程内存关系, 每增加4个字符会增加8Byte内存空间大小,无论中文英文字符。
ClassMethod Store9()
{
	w "英文所占内存大小:",!
	s str = ""
	w 0 _ " :" _ str _ ":" _$s ,!
	for i = 1 : 1 : 40 {
		s str = str _ "x"
		w i _ " :" _ str _ ":" _$s ,!
	}


	w "中文所占内存大小:",!
	w $s,!
	s name = "姚"
	w $s,!
	s name = "姚鑫"
	w $s,!
	s name = "姚鑫姚"
	w $s,!
	s name = "姚鑫姚鑫"
	w $s,!
	s name = "姚鑫姚鑫姚"
	w $s,!
	s name = "姚鑫姚鑫姚鑫"
	w $s,!
	s name = "姚鑫姚鑫姚鑫姚"
	w $s,!
	s name = "姚鑫姚鑫姚鑫姚鑫"
	w $s,!
	s name = "姚鑫姚鑫姚鑫姚鑫姚鑫姚鑫"
	w $s,!
	s name = "姚鑫姚鑫姚鑫姚鑫姚鑫姚鑫姚鑫姚鑫"
	w $s,!
}
USER> d ##class(M.Store).Store9()
英文所占内存大小:
0 ::268311440
1 :x:268311432
2 :xx:268311432
3 :xxx:268311432
4 :xxxx:268311424
5 :xxxxx:268311424
6 :xxxxxx:268311424
7 :xxxxxxx:268311424
8 :xxxxxxxx:268311408
9 :xxxxxxxxx:268311408
10 :xxxxxxxxxx:268311408
11 :xxxxxxxxxxx:268311408
12 :xxxxxxxxxxxx:268311408
13 :xxxxxxxxxxxxx:268311408
14 :xxxxxxxxxxxxxx:268311408
15 :xxxxxxxxxxxxxxx:268311408
16 :xxxxxxxxxxxxxxxx:268311376
17 :xxxxxxxxxxxxxxxxx:268311376
18 :xxxxxxxxxxxxxxxxxx:268311376
19 :xxxxxxxxxxxxxxxxxxx:268311376
20 :xxxxxxxxxxxxxxxxxxxx:268311376
21 :xxxxxxxxxxxxxxxxxxxxx:268311376
22 :xxxxxxxxxxxxxxxxxxxxxx:268311376
23 :xxxxxxxxxxxxxxxxxxxxxxx:268311376
24 :xxxxxxxxxxxxxxxxxxxxxxxx:268311376
25 :xxxxxxxxxxxxxxxxxxxxxxxxx:268311376
26 :xxxxxxxxxxxxxxxxxxxxxxxxxx:268311376
27 :xxxxxxxxxxxxxxxxxxxxxxxxxxx:268311376
28 :xxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311376
29 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311376
30 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311376
31 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311376
32 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311312
33 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311312
34 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311312
35 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311312
36 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311312
37 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311312
38 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311312
39 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311312
40 :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:268311312
中文所占内存大小:
268311312
268311304
268311304
268311304
268311296
268311296
268311296
268311296
268311280
268311280
268311248

内存不足原理

如上一节所述,我们知道了什么情况下内存会发生变化。这里我们模拟常见内存溢出的一种情况:

在处理大量数据时,使用多维数组用于分类或汇总数据,如果多维数据下标节点越来越多,那么使用的内存会越来越多。如果未及时释放已使用的内存,会导致内存耗尽。示例如下:

ClassMethod Store11()
{
	for {
		s yx($i(yx)) = $i(yx)
	}
	q $$$OK
}
USER> d ##class(M.Store).Store11()
 
  s yx($i(yx)) = $i(yx)
  ^
<STORE>zStore11+2^M.Store.1
USER 3f2>

原理:$STORAGE值可以是正数,也可以是负数。值为零并不表示没有可用存储,但表示存储极度短缺。如果$STORAGE减少到小于或接近与零,则会在某个时刻发生<store>错误。例如,如果$STORAGE减少到40,则为另一个局部变量分配存储可能会由于<store>错误而失败,这表明没有足够的可用存储空间来存储局部变量值或建立新的堆栈级别。

ClassMethod Store11()
{
	for {
		s yx($i(yx)) = $i(yx)
		if ($s < 1000){
			w $s,!
		}
	}
	q $$$OK
}

USER> d ##class(M.Store).Store11()
216
176
120
64
40
 
  s yx($i(yx)) = $i(yx)
  ^
<STORE>zStore11+2^M.Store.1

实际上<STORE>内存错误,可以通过设置陷阱来捕获异常。但是进入陷阱时,并不会主动释放内存。示例如下:

ClassMethod Store12()
{
	s $zt = "Error"
	for {
		s yx($i(yx)) = $i(yx)
	}
	q $$$OK
Error
	s $zt = ""
	w "内存溢出时内存大小:" _ $s,!
	q $ze
}
USER> d ##class(M.Store).Store12()
内存溢出时内存大小:440

<store>错误发生并用陷阱进行拦截时,系统会自动为进程提供1MB的额外内存,用与错误处理。系统不会更改$ZSTORAGE的大小,允许$STORAGE进一步进入负数值。示例如下:

在这里插入图片描述

当第一个<store>错误发生时,系统在内部将进程指定为内存不足状态。而在此低内存状态下,该进程可以继续分配内存,并且$STORAGE的值可以继续减少到更低的负数。在此低内存状态下,进程可能会释放一些已分配的内存,从而导致$STORAGE的值上升。因此,$STORAGE的值可以在一个值范围内上升或下降,而不会发出额外的<store>错误。

注:第一个<store>错误提供了一些内存缓冲,允许进程调用诊断、执行磁盘保存、正常退出、释放内存并继续。

注:当发生第一个<store>错误进程会消耗额外的内存。当$STORAGE的值达到-1048576时,会出现第二个<STORE>错误。如果进程发生第二个<STORE>错误,则没有更多的内存可供该进程使用,并且进一步的进程操作将变得不可预测。这个进程会立即终止。

注:如果在陷阱当中发生内存再次溢出,进程是直接关闭的。即使设置了$zt= "",也不管用,这种情况如果陷阱中有记录日志或有解锁操作等,将不会就即使,会发生锁无法即使释放。

如下示例,锁永远也不会得到释放。

ClassMethod Store14()
{
	s $zt = "Error"
	

	w "加锁",!
	l +^yx("node"):3
	
	for {
		s yx($i(yx)) = $i(yx)
	}
	q $$$OK
Error
	s $zt = ""
	w "内存溢出时内存大小:" _ $s,!
	for {
		s yx($i(yx)) = $i(yx)
		w $s,!
	}
	
	w "陷阱内存溢出,解锁失败",!
	l -^yx("node"):3
	q $ze
}

解决方案

要解决内存不足的问题首先要做到以下几点:

  1. 在使用多维数组时,要设置陷阱进行异常拦截。

  2. 在发生内存溢出时,在陷阱中将多维数据kill删除掉,恢复内存。

  3. 如果发生了二次内存溢出。需要讲多维数组方法声明为单独的方法。用于外层接口调用,进行陷阱二次拦截。

示例如下:

注:$SYSTEM.Process.MemoryAutoExpandStatus()方法可以提示出内存溢出的原因。

模拟二次内存溢出代码如下:

ClassMethod Store14()
{
	s $zt = "Error"
	

	w "加锁",!
	l +^yx("node"):3
	
	for {
		s yx($i(yx)) = $i(yx)
	}
	q $$$OK
Error
	s $zt = ""
	w "第一次内存溢出错误:" _ $ze,!
	w "陷阱错误代码:" _ $SYSTEM.Process.MemoryAutoExpandStatus(),!
	if ($SYSTEM.Process.MemoryAutoExpandStatus() = 1) {
		w "1——抛出<STORE>错误,因为进程超过了$ZSTORAGE值,并且没有自动扩展$ZSTORAGE值。",!
	}
	b ; 陷阱
	for {
		s yx($i(yx)) = $i(yx)
		w $s,!
	}
	
	w "陷阱内存溢出,解锁失败",!
	l -^yx("node"):3
	q $ze
}

基于上述第三点,需要单独的方法去调用,用于外层接口调用,进行陷阱二次拦截。示例如下:

ClassMethod Store15()
{
	
	s $zt = "Error"
	w "开始时内存:"_ $s,!
	d ..Store14()
	
	w "结束时内存:"_ $s,!
	q $$$OK
Error
	s $zt = ""
	w "陷阱中剩余:"_ $s,!
	w "陷阱错误代码:" _ $SYSTEM.Process.MemoryAutoExpandStatus(),!
	if ($SYSTEM.Process.MemoryAutoExpandStatus() = 2) {
		w "2——抛出<STORE>错误,因为进程超过了$ZSTORAGE值,并且$ZSTORAGE值被自动扩展了1M。",!
	}
	w "第二次内存溢出错误:" _ $ze,!
	l -^yx("node"):3
	w "解锁",!
	
	q $ze
}

在这里插入图片描述

根据上图可观察到,在外层陷阱进行拦截到第二次内存溢出错误时,可发现系统为我们自动清理了内存,并将内存恢复到$ZSTORAGE最大值268302712。并且也成功解锁。

注:上面示例是为了解决内存二次溢出的情况,通过这种方式防止进程直接结束,实际上应该在第一次内存溢出时,就应该将多维数组进行kill恢复内存。

注:实际上不应该在陷阱当中写入过多的业务逻辑,导致二次内存溢出。

以上是个人对IRIS/Caché进程内存溢出的一些理解,由于个人能力有限,欢迎大家提出意见,共同交流。

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

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

相关文章

群晖 nas 自建 ntfy 通知服务(梦寐以求)

目录 一、什么是 ntfy ? 二、在群晖nas上部署ntfy 1. 在Docker中安装ntfy 2. 设置ntfy工作文件夹 3. 启动部署在 docker 中的 ntfy&#xff08;binwiederhier/ntfy&#xff09; 三、启动配置好后&#xff0c;如何使用ntfy 1. 添加订阅主题&#xff08; Subscribe to topic…

六种不同的CRM系统类型分别有哪些特点?

企业想要管理销售&#xff0c;可以选择CRM系统&#xff1b;企业想要优化业务流程&#xff0c;可以选择CRM系统&#xff1b;企业想要提高收入&#xff0c;可以选择CRM系统。下面来说说&#xff0c;CRM是什么&#xff1f;六种常见CRM系统类型对比。 什么是CRM&#xff1f; CRM是…

当执行汇编指令MOV [0001H] 01H时,CPU都做了什么?

今天和几位单位大佬聊天时&#xff0c;讨论到一个非常有趣的问题-当程序执行MOV [0001H], 01H计算机实际上都做了哪些工作&#xff1f;乍一看这个问题平平无奇&#xff0c;CPU只是把立即数01H放在了地址为0001的内存里&#xff0c;但仔细想想这个问题远没有那么简单&#xff0c…

Synchronized八锁

/** * Description: 8 锁 * 1 标准访问&#xff0c;先打印短信还是邮件 ------sendSMS ------sendEmail 2 停 4 秒在短信方法内&#xff0c;先打印短信还是邮件 ------sendSMS ------sendEmail 3 新增普通的 hello 方法&#xff0c;是先打短信还是 hello ------getHello ------…

阿里云服务器IP地址查看方法(公网/私网)

阿里云服务器IP地址在哪查看&#xff1f;在云服务器ECS管理控制台即可查看&#xff0c;阿里云服务器IP地址包括公网IP和私有IP&#xff0c;阿里云百科分享阿里云服务器IP地址查询方法&#xff1a; 目录 阿里云服务器IP地址查询 阿里云服务器IP地址查询 1、登录到阿里云服务器…

HTML基础知识,网页和报表都可用

首先我们先介绍一下网页&#xff1a; 网页时构成网站的基本元素&#xff0c;它通常由图片&#xff0c;链接&#xff0c;文字&#xff0c;声音&#xff0c;视频等元素组成。通常我们看到的网页&#xff0c;常见以.htm或.html后缀结尾的文件&#xff0c;因此我们把它俗称为HTML文…

易服客工作室:Elementor AI简介 – 彻底改变您创建网站的方式

Elementor 作为领先的 WordPress 网站构建器&#xff0c;是第一个添加本机 AI 集成的。Elementor AI 的第一阶段将使您能够生成和改进文本和自定义代码&#xff08;HTML、自定义代码和自定义 CSS&#xff09;。我们还已经在进行以下阶段的工作&#xff0c;其中将包括基于人工智…

uniapp 使用 uni push 2.0 推送消息

因为之前使用uni push 1.0&#xff0c;开通账号和配置厂商就不写了。只说一点&#xff0c;配置厂商很重要&#xff0c;不然收不到离线推送的消息。那么就直接开始咯&#xff01;&#xff01;&#xff01; 一、创建并关联云服务空间 1.创建云服务空间&#xff0c;右键项目【创…

『C语言初阶』第八章 -隐式类型转换规则

前言 今天小羊又来给铁汁们分享关于C语言的隐式类型转换规则&#xff0c;在C语言中类型转换方式可分为隐式类型转换和显式类型转换(强制类型转换)&#xff0c;其中隐式类型转换是由编译器自动进行&#xff0c;无需程序员干预&#xff0c;今天小羊课堂说的就是关于隐式类型转换…

阻塞和非阻塞,同步和异步

文章目录 典型的一次IO的两个阶段IO多路复用是同步还是异步&#xff1f; 典型的一次IO的两个阶段 数据就绪和数据读写 同步&#xff1a;需要应用程序自己操作 IO多路复用是同步还是异步&#xff1f; epoll也是同步的 具体数据读取还是通过应用程序自己完成的 只有使用了特…

快速开发平台 WebBuilder 的功能特点

WebBuilder 是一款强大&#xff0c;全面和高效的应用开发和运行平台。基于浏览器的集成开发环境&#xff0c;智能化的设计&#xff0c;能轻松完成常规桌面应用和面向手机等的移动应用开发。高效、稳定和可扩展的特点&#xff0c;适合复杂企业级应用的运行。跨平台、数据库和浏览…

线性回归例子

转自&#xff1a;https://www.cnblogs.com/BlairGrowing/p/15061912.html 刚开始接触深度学习和机器学习&#xff0c;由于是非全日制&#xff0c;也没有方向感&#xff0c;缺乏学习氛围、圈子&#xff0c;全靠自己业余时间瞎琢磨&#xff0c;犹如黑夜中的摸索着过河。 只是顺…

易服客工作室:WordPress是什么?初学者的解释

目录 什么是WordPress&#xff1f; WordPress可以制作什么类型的网站&#xff1f; 谁制作了WordPress&#xff1f;它已经存在多久了&#xff1f; 谁使用 WordPress&#xff1f; 白宫网站 微软 滚石乐队 为什么要使用 WordPress&#xff1f; WordPress 是免费且…

【不支持发行版本 5】错误解决

说明&#xff1a;启动项目报下面的错误&#xff0c;不支持发行版本 5 解决&#xff1a;在pom文件中添加下面这两行配置&#xff0c;修改成你自己安装的jdk版本 <properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target&g…

TienChin 新建业务菜单

首先是移动菜单&#xff0c;参考下图将菜单移动到下图结构&#xff1a; 我这里将系统监控&#xff0c;系统工具都移动到了系统管理下面&#xff0c;并且排了个序&#xff0c;将多级菜单放在了一起&#xff0c;这样看起来更加的清晰。 修改一下系统管理(100)与TienChin健身官网(…

Blazor:组件生命周期和刷新机制详解

文章目录 前言生命周期子组件设置事件刷新为什么传入非基础元素&#xff0c;会强制刷新 自动刷新逻辑如何解决委托事件强制刷新问题 前言 对于组件化来说&#xff0c;生命周期是必须掌握的知识&#xff0c;只有掌握了生命周期才能更好的去设置数据的变化。 Blazor 生命周期 微…

99. for循环练习题-3种方式输出0-9

【目录】 文章目录 99. for循环练习题-3种方式输出0-91. for循环和while循环的区别2. 输出 0~(n-1)的数字2.1 基础代码2.2 自定义函数代码2.3 异常处理语句代码 【正文】 99. for循环练习题-3种方式输出0-9 1. for循环和while循环的区别 for循环和while循环都用于重复执行特定…

AI Infra工具关键能力解析:数据准备、模型训练、模型部署与整合

在预训练大模型时代,我们可以从应用落地过程里提炼出标准化的工作流,AI Infra的投资机会得以演绎。传统ML时代AI模型通用性较低,项目落地停留在“手工作坊”阶段,流程难以统一规范。而大规模预训练模型统一了“从0到1”的技术路径,具备解决问题的泛化能力,能够赋能“从1到…

WiFi小工具homedale,可以切换同名WiFi节点

有一个很小众的需求&#xff0c;就是多个路由器组网时候&#xff0c;PC有时不会自动切换同名WiFi&#xff0c;homedale这个工具可以满足手动切换需求 这个界面可以看到所有节点列表&#xff0c;可以看到有很多同名的 可以选择自己想要的那个&#xff0c;比如信道/信号强度&am…

avd(emulator)设置代理以及与pc互访

默认pc127.0.0.1是还回ip&#xff0c;模拟器使用127.0.0.1指向了自己&#xff0c;模拟器使用10.0.2.2指代pc地址&#xff0c;这点在官方文档有说明可以查看,所以想要挂代理抓包就需要为模拟器设置代理为10.0.2.2 安卓模拟器设置代理 前提&#xff1a;本机开启了代理如&#xf…