Linux 查看磁盘空间可以使用 df 和 du 命令。dfdf 以磁盘分区为单位查看文件系统，可以获取硬盘被占用了多少空间，目前还剩下多少空间等信息。例如，我们使用df -h命令来查看磁盘信息， -h 选项为根据大小适当显示：显示内容参数说明：Filesystem：文件系统Size： 分区大小Used： 已使用容量Avail： 还可以使用的容量Use%： 已用百分比Mounted on： 挂载点相关命令：df -hl：查看磁盘剩余空间df -h：查看每个根路径的分区大小du -sh [目录名]：返回该目录的大小du -sm [文件夹]：返回该文件夹总M数du -h [目录名]：查看指定文件夹下的所有文件大小（包含子文件夹）dudu 的英文原义为 disk usage，含义为显示磁盘空间的使用情况，用于查看当前目录的总大小。例如查看当前目录的大小：# du -sh 605M 显示指定文件所占空间：# du log2012.log 300 log2012.log 方便阅读的格式显示test目录所占空间情况：# du -h test 608K test/test6 308K test/test4 4.0K test/scf/lib 4.0K test/scf/service/deploy/product 4.0K test/scf/service/deploy/info 12K test/scf/service/deploy 16K test/scf/service 4.0K test/scf/doc 4.0K test/scf/bin 32K test/scf 8.0K test/test3 1.3M test du 命令用于查看当前目录的总大小：-s：对每个Names参数只给出占用的数据块总数。-a：递归地显示指定目录中各文件及子目录中各文件占用的数据块数。若既不指定-s，也不指定-a，则只显示Names中的每一个目录及其中的各子目录所占的磁盘块数。-b：以字节为单位列出磁盘空间使用情况（系统默认以k字节为单位）。-k：以1024字节为单位列出磁盘空间使用情况。-c：最后再加上一个总计（系统默认设置）。-l：计算所有的文件大小，对硬链接文件，则计算多次。-x：跳过在不同文件系统上的目录不予统计。-h：以K，M，G为单位，提高信息的可读性。
使用Navicat Keygen激活(破解)Navicat Premium 12
1、到Navicat官网使用版本进行安装，具体操作不再详述。Navcat官网下载，或者直接在本文末下载（已包含Keygen）2、到GitHub下载DoubleLabyrinth大神发布的Navicat Keygen，具体操作不再详述。Navicat Keygen下载地址：https://github.com/DoubleLabyrinth/navicat-keygen/releases，对应的中文使用说明链接：https://github.com/DoubleLabyrinth/navicat-keygen/blob/windows/doc/how-to-use.windows.zh-CN.md 可以直接参照此说明进行操作，忽略后文；3、打开cmd，cd到navicat-keygen-for-x64目录；4、输入命令：navicat-patcher.exe "C:Program FilesPremiumSoftNavicat Premium 12" 回车执行，此处默认安装Navicat Premium文件夹为C:Program FilesPremiumSoftNavicat Premium 12，注意含空格的路径需要使用半角双引号包起来；5、回车确认，等待执行完成，如下图；6、此时在目录内可以看到生成的RegPrivateKey.pem文件；7、继续在cmd中输入命令：navicat-keygen.exe -text RegPrivateKey.pem 并执行；8、选择1(Premium)然后回车；9、选择1(中文)然后回车；10、选择产品版本12，然后回车；11、生成了产品序列号，将序列号填入注册页面；12、在点击激活之前，断开本地电脑互联网链接(重要)；13、此时点击激活，会出现激活服务器不可用的提示，然后选择手动激活；14、当出现如下界面时，到cmd继续操作；15、分别输入Name和Organization并回车，演示为随意填写；16、在request code后面将注册界面的请求码复制过来，回车确认，再回车执行，执行完成后得到红框中的激活码；17、将激活码复制到注册界面的激活码文本框，点击确认，完成激活，整个操作结束。18、激动人心的时刻。感谢大神提供的工具，谢谢！附下载地址：[scode type="blue"]链接：https://pan.baidu.com/s/1jwmQoiCDGxHinAqLZTwqEw 提取码：itt0[/scode]
常用的 ping，tracert，nslookup 一般用来判断主机的网络连通性，其实 Linux 下有一个更好用的网络联通性判断工具，它可以结合ping nslookup tracert 来判断网络的相关特性，这个命令就是 mtr。mtr 全称 my traceroute，是一个把 ping 和 traceroute 合并到一个程序的网络诊断工具。[scode type="yellow"]traceroute默认使用UDP数据包探测，而mtr默认使用ICMP报文探测，ICMP在某些路由节点的优先级要比其他数据包低，所以测试得到的数据可能低于实际情况。[/scode]安装方法1.Windows系统可以直接在https://cdn.ipip.net/17mon/besttrace.exe下载BestTrace工具并安装。也可以在https://github.com/oott123/WinMTR/releases GitHub上下载MTR专用工具，该工具为免安装，下载后可以直接使用。2.Linux可以直接运行命令进行安装。# Debian/Ubuntu 系统 apt install mtr # RedHat/CentOS 系统 yum install mtr 3.Apple客户端可以在App store搜索Best NetTools下载安装4.Android客户端：可以在Google Play上下载TracePing，但是由于国内Google Play无法访问，笔者自行下载下来，可以直接访问 https://dwz.cn/KCdNPH4c 下载TracePing。使用MTR使用非常简单，查看本机到 qq.com 的路由以及连接情况直接运行如下命令：mtr qq.com MTR qq.com 测试界面具体输出的参数含义为：第一列是IP地址丢包率：Loss已发送的包数：Snt最后一个包的延时：Last平均延时：Avg最低延时：Best最差延时：Wrst方差（稳定性）：StDev参数说明r or --report 使用 mtr -r qq.com 来打印报告，如果不使用 -r or --report 参数 mtr 会不断动态运行。使用 report 选项， mtr 会向 qq.com 主机发送 10 个 ICMP 包，然后直接输出结果。通常情况下 mtr 需要几秒钟时间来输出报告。mtr 报告由一系列跳数组成，每一跳意味着数据包通过节点或者路由器来达到目的主机。一般情况下 mtr 前几跳都是本地 ISP，后几跳属于服务商比如 腾讯数据中心，中间跳数则是中间节点，如果发现前几跳异常，需要联系本地 ISP 服务提供上，相反如果后几跳出现问题，则需要联系服务提供商，中间几跳出现问题，则需要联系运营商进行处理默认使用 -r 参数来生成报告，只会发送10个数据包，如果想要自定义数据包数量，可以使用 -c 参数-s or --packetsize 使用 -s 来指定ping数据包的大小mtr -s 100 qq.com 100 bytes 数据包会用来发送，测试，如果设置为负数，则每一次发送的数据包的大小都会是一个随机数。-c指定发送数量mtr -c 100 qq.com -n不进行主机解释使用 -n 选项来让 mtr 只输出 IP，而不对主机 host name 进行解释mtr -n qq.com MTR结果分析当我们分析 MTR 报告时候，最好找出每一跳的任何问题。除了可以查看两个服务器之间的路径之外，MTR 在它的七列数据中提供了很多有价值的数据统计报告。Loss% 列展示了数据包在每一跳的丢失率。Snt 列记录的多少个数据包被送出。使用 –report 参数默认会送出10个数据包。如果使用 –report-cycles=[number-of-packets] 选项，MTR 就会按照 [number-of-packets] 指定的数量发出 ICMP 数据包。Last, Avg, Best 和 Wrst 列都标识数据包往返的时间，使用的是毫秒（ ms ）单位表示。Last 表示最后一个数据包所用的时间， Avg 表示评价时间， Best 和 Wrst 表示最小和最大时间。在大多数情况下，平均时间（ Avg）列需要我们特别注意。最后一列 StDev 提供了数据包在每个主机的标准偏差。如果标准偏差越高，说明数据包在这个节点的延时越不相同。标准偏差会让您了解到平均延时是否是真的延时时间的中心点，或者测量数据受到某些问题的干扰。例如，如果标准偏差很大，说明数据包的延迟是不确定的。一些数据包延迟很小（例如：25ms），另一些数据包延迟很大（例如：350ms）。当10个数据包全部发出后，得到的平均延迟可能是正常的，但是平均延迟是不能很好的反应实际情况的。如果标准偏差很高，使用最好和最坏的延迟来确定平均延迟是一个较好的方案。在大多数情况下，您可以把 MTR 的输出分成三大块。根据配置，第二或第三跳一般都是您的本地 ISP，倒数第二或第三跳一般为您目的主机的ISP。中间的节点是数据包经过的路由器。当分析 MTR 的输出时，您需要注意两点：loss 和 latency。网络丢包如果在任何一跳上看到 loss 的百分比，这就说明这一跳上可能有问题了。当然，很多服务提供商人为限制 ICMP 发送的速率，这也会导致此问题。那么如何才能指定是人为的限制 ICMP 传输 还是确定有丢包的现象？此时需要查看下一跳。如果下一跳没有丢包现象，说明上一条是人为限制的。如下示例：在此例中，第4跳发生了丢包现象，但是接下来几条都没任何丢包现象，说明第二跳的丢包是人为限制的。如果在接下来的几条中都有丢包，那就可能是第二跳有问题了。请记住，ICMP 包的速率限制和丢失可能会同时发生。从上面的图中，您可以看从第13跳和第17跳都有 10% 的丢包率，从接下来的几跳都有丢包现象，但是最后15,16跳都是100%的丢包率，我们可以猜测到100%的丢包率除了网络糟糕的原因之前还有人为限制 ICMP。所以，当我们看到不同的丢包率时，通常要以最后几跳为准。还有很多时候问题是在数据包返回途中发生的。数据包可以成功的到达目的主机，但是返回过程中遇到“困难”了。所以，当问题发生后，我们通常需要收集反方向的 MTR 报告。此外，互联网设施的维护或短暂的网络拥挤可能会带来短暂的丢包率，当出现短暂的10%丢包率时候，不必担心，应用层的程序会弥补这点损失。网络延迟除了可以通过MTR报告查看丢包率，我们也还可以看到本地到目的之间的时延。因为是不通的位置，延迟通常会随着条数的增加而增加。所以，延迟通常取决于节点之间的物理距离和线路质量。MTR查看网络延迟从上面的MTR报告截图中，我们可以看到从第11跳到12跳的延迟猛增，直接导致了后面的延迟也很大，一般有可能是11跳到12跳属于不通地域，物理距离导致时延猛增，也有可能是第12条的路由器配置不当，或者是线路拥塞。需要具体问题进行具体的分析。然而，高延迟并不一定意味着当前路由器有问题。延迟很大的原因也有可能是在返回过程中引发的。从这份报告的截图看不到返回的路径，返回的路径可能是完全不同的线路，所以一般需要进行双向MTR测试。注：ICMP 速率限制也可能会增加延迟，但是一般可以查看最后一条的时间延迟来判断是否是上述情况。根据MTR结果解决网络问题MTR 报告显示的路由问题大都是暂时性的。很多问题在24小时内都被解决了。大多数情况下，如果您发现了路由问题，ISP 提供商已经监视到并且正在解决中了。当您经历网络问题后，可以选择提醒您的 ISP 提供商。当联系您的提供商时，需要发送一下 MTR 报告和相关的数据。没有有用的数据，提供商是没有办法去解决问题的。然而大多数情况下，路由问题是比较少见的。比较常见的是因为物理距离太长，或者上网高峰，导致网络变的很慢。尤其是跨越大西洋和太平洋的时候，网络有时候会变的很慢。这种情况下，建议就近接入客户的节点。
PS2020(Adobe Photoshop 2020简体中文版) 21.0.1 中文免费版
[scode type="blue"]本软件为内置破解，安装完成即可使用，无需其他破解激活操作！本软件在win10 64系统测试通过！[/scode]PhotoShop 2020中文破解版是一款非常好用的专业图像处理软件，PhotoSho p2020对于图片的处理能力已经不需要多少，摄像，摄影，媒体和视频从事人员的专业装机的必备选择。不仅对于专业的摄影者有用，快来下载使用2020最新版吧！PS 2020安装教程1、下载软件包并解压，断开网络，以管理员身份运行set-up.exe2、选择语言和安装位置3、等待产品安装4、安装完成，点击关闭PS2020功能1、增强的文件浏览器在photoshop8.0中，文件浏览器担当着数字图像处理中心的作用。现在，借助于标记、关键字和可编辑的元数据，您可以使用文件浏览器快速组织和找到需要的图像资源。不必先在Photoshop中打开图像文件就可以对一组图像执行批处理过程。2、轻松地自定键盘快捷键为菜单项、工具和调板命令创建、编辑并存储多个键盘快捷键组合，这样您就可很方便地使用最常用的功能。3、快速创建、查看和编辑自定文件信息使用文件浏览器可以通过可编辑的元数据快速搜索文件，而不必打开每一个文件。使用“文件简介对话框中的自定面板和字段完全自定图像元数据，并使用文件浏览器一次编辑一幅或多幅图像的元数据。4、创建幻灯片放映和 PDF 演示文稿轻松地将多个文件合并成一个多页 Adobe PDF 文档，并带有可选的页面转换效果和安全功能。5、协作使用 Web 照片画廊使用专业设计的 Web 照片画廊模板，可以包括对客户反馈的支持而不需要额外的 Web 编码。6、跟踪编辑历史记录在外部的日志文件以及附加到各个文件上的元数据中存储编辑历史记录。7、轻松地访问和使用多个滤镜新增的滤镜库将photoshop8.0滤镜集中在一个易于使用的对话框中。现在，您可以一次访问、控制和应用多个滤镜。利用新的更大的预览效果图，可以更轻松地规划堆叠的滤镜效果。（请参阅使用“滤镜库。）8、使用增强的脚本功能使用自定或新增的内置脚本来自动完成重复性任务，例如，将图层输出到文件中或将图层复合存储为 Adobe PDF文件的不同页面，从而节省时间。请参阅 Photoshop CS/Scripting Guide 文件夹中提供的文档。9、自定义帮助菜单通过从“帮助菜单中选取新的操作方法主题来使用它们。 或者，创建您自己的操作方法主题，并让它显示在“帮助菜单中。[scode type="blue"]下载地址，评论可见，失效请联系。[/scode]
根据设计领域的最新趋势，推荐10个值得关注的CSS生成工具，以帮助你构建漂亮炫酷实用的UI界面。这些工具将有助于提升设计人员和前端开发人员的工作。1、Neumorphism地址：https://neumorphism.io/它创造了一种全新的UI风格。来自世界各地的设计师已经在Dribbble和Behance上看到了引人注目的中性设计。但是这个工具，可以直接在线调试UI风格，并直接生成CSS代码。2、带有渐变的图标地址：https://www.iconshock.com/svg-icons/在设计的时候，我们都注重简约。不过，有时我们喜欢添加一些渐变效果，这样会显得图标层次更加丰富一些，而这个工具，就可以帮助我们提升工作效率，哪怕你没有设计能力，你也可以设计出漂亮的图标。而这些精美的图标和大量渐变可为你提供创作灵感。3、Interactions地址：https://easings.co/在一系列界面上测试常见的缓动曲线。或生成自己的自定义贝塞尔曲线。没有比这更顺畅的交互和动画效果了。 我经常与开发人员合作，向他发送在此生成器中设置的交互。这将使你的数字产品保持美观和正常工作。在这里您可以计算出交互作用，例如：图片轮播侧面菜单滚动底部菜单模态4、大型数据库地址：https://bansal.io/pattern-css仅用CSS库就可以完成美丽图案填充空背景效果。 在此页面上，你可以为你的数字产品制定理想的背景。你也可以将其用作物品和照片的装饰。样式截图效果如下：5、自定义形状分隔线地址：https://www.shapedivider.app/划分布局和形状已经变得非常时尚。使用此工具，你可以创建可响应的波形和自定义形状分隔线。6、动画地址：https://animista.net/庞大的动画库。在这里，你将找到可用于组件，照片和文本的基本，以及更高级的动画。7、Maskclip-path属性允许你通过将元素裁剪为基本形状（圆形，椭圆形，多边形或插图）或SVG源来在CSS中制作复杂的形状。CSS动画和过渡可以使用两个或多个具有相同点数的剪切路径形状。8、动画按钮地址：https://tympanus.net/Development/MagneticButtons/index.html有一些有趣的悬停动画的磁性按钮。设计按钮时，请记住，还可以选择对它们进行动画处理。但是，要小心，它并不适合所有地方。这些按钮的主要思想是它们具有磁性并跟随鼠标指针。除此之外，还有一些有趣的悬停动画可以玩。要探索的一件非常不错的事情是附加元素（例如阴影或另一条线）的运动。通过不同地移动按钮元素而创建的视差效果，使动画具有很好的扭曲效果。9、背景图案地址：https://www.magicpattern.design/tools/css-backgrounds你可以在项目中使用漂亮的纯CSS背景图案。在创造页面上，你可以找到非常不同的码型生成器。但是，请记住，其中一些需要高级套餐。10、SVG波浪地址：https://svgwave.in/最后一个工具是波浪效果生成器。它使用简单，可以制作多个图层并对其进行修改。[scode type="share"]转自：高级前端进阶译文：小爱原文链接：https://mattkarski.medium.com/10-amazing-css-generators-for-ui-design-1f790791c4e7[/scode]
如何在Linux中使用find根据时间戳查找文件
Linux中的find命令用于根据不同的参数搜索文件和文件夹。这些参数可以是文件名，大小，文件类型等。这样的参数之一就是文件的时间戳。在Linux（以及所有基于Unix的文件系统）中，每个文件都有3个时间戳记：上次修改时间上次访问时间上次状态更改时间（即，当更改文件的元数据（如权限）时）让我们看看如何使用find来基于每个时间戳来搜索文件。在Linux中查找文件时间戳首先，我们可以在Linux中运行“stat ”命令来获取文件的所有这些时间戳。例如，对于名称为“nginx-1.20.1.tar.gz”的文件，运行：[root@siyueCloud siyue]# stat nginx-1.20.1.tar.gz 根据时间戳查找文件现在，要基于时间戳查找文件，我们使用手册页中'-newerXY'的find参数。[root@siyueCloud siyue]# man find 因此，在参数中'-newerXY'，我们可以将X作为a，c或m分别用于最后访问，最后状态更改和最后修改时间，将Y用作t，以便我们可以将下一个参数作为时间戳字符串。注意：在基于Unix的文件系统中，不保留文件的创建时间概括地说，要运行的命令如下所示：find <directory_path> -newer<a/m/c>t ‘<timestamp>’ 在这里，时间戳的格式应为：'YYYY-MM-DD HH:MM:SS'。让我们在一个只有几个文件的文件夹中尝试这个方法，在指定的时间之后只有两个文件被访问、修改和状态更改。[root@siyueCloud siyue]# find . -newerat '2021-07-08 08:00' [root@siyueCloud siyue]# find . -newerct '2021-07-08 08:00' [root@siyueCloud siyue]# find . -newermt '2021-07-08 08:00' 如果两个文件的时间戳确实大于指定的时间，请使用“ stat”进行验证。[root@siyueCloud siyue]# stat nginx-1.20.1.tar.gz php-8.0.7.tar.gz 总结我们已经学习了如何使用命令find的参数'-newerXY'来根据时间戳搜索文件。请注意，您也可以将另一个文件用作参考时间戳，而不用显式指定时间戳，在这种情况下，可以跳过参数中的“ t”。
现实企业级Java应用开发、维护中，有时候我们会碰到下面这些问题：OutOfMemoryError，内存不足内存泄露线程死锁锁争用（Lock Contention）Java进程消耗CPU过高......这些问题在日常开发、维护中可能被很多人忽视（比如有的人遇到上面的问题只是重启服务器或者调大内存，而不会深究问题根源），但能够理解并解决这些问题是Java程序员进阶的必备要求。本文将对一些常用的JVM性能调优监控工具进行介绍，希望能起抛砖引玉之用。一、 jps(Java Virtual Machine Process Status Tool) ：基础工具jps主要用来输出JVM中运行的进程状态信息。语法格式如下：jps [options] [hostid] 如果不指定hostid就默认为当前主机或服务器。命令行参数选项说明如下：-q 不输出类名、Jar名和传入main方法的参数 -m 输出传入main方法的参数 -l 输出main类或Jar的全限名 -v 输出传入JVM的参数 比如下面：root@ubuntu:/# jps -m -l 2458 org.artifactory.standalone.main.Main /usr/local/artifactory-2.2.5/etc/jetty.xml 29920 com.sun.tools.hat.Main -port 9998 /tmp/dump.dat 3149 org.apache.catalina.startup.Bootstrap start 30972 sun.tools.jps.Jps -m -l 8247 org.apache.catalina.startup.Bootstrap start 25687 com.sun.tools.hat.Main -port 9999 dump.dat 21711 mrf-center.jar 二、 jstackjstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下：jstack [option] pid jstack [option] executable core jstack [option] [server-id@]remote-hostname-or-ip 命令行参数选项说明如下：-l long listings，会打印出额外的锁信息，在发生死锁时可以用jstack -l pid来观察锁持有情况-m mixed mode，不仅会输出Java堆栈信息，还会输出C/C++堆栈信息（比如Native方法） jstack可以定位到线程堆栈，根据堆栈信息我们可以定位到具体代码，所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息，用到的命令有ps、top、printf、jstack、grep。第一步先找出Java进程ID，我部署在服务器上的Java应用名称为mrf-center：root@ubuntu:/# ps -ef | grep mrf-center | grep -v grep root 21711 1 1 14:47 pts/3 00:02:10 java -jar mrf-center.jar 得到进程ID为21711，第二步找出该进程内最耗费CPU的线程，可以使用ps -Lfp pid或者ps -mp pid -o THREAD, tid, time或者top -Hp pid，我这里用第三个，输出如下：TIME列就是各个Java线程耗费的CPU时间，CPU时间最长的是线程ID为21742的线程，用printf "%x " 21742 得到21742的十六进制值为54ee，下面会用到。OK，下一步终于轮到jstack上场了，它用来输出进程21711的堆栈信息，然后根据线程ID的十六进制值grep，如下：root@ubuntu:/# jstack 21711 | grep 54ee "PollIntervalRetrySchedulerThread" prio=10 tid=0x00007f950043e000 nid=0x54ee in Object.wait() [0x00007f94c6eda000] 可以看到CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait()，我找了下我的代码，定位到下面的代码：// Idle wait getLog().info("Thread [" + getName() + "] is idle waiting..."); schedulerThreadState = PollTaskSchedulerThreadState.IdleWaiting; long now = System.currentTimeMillis(); long waitTime = now + getIdleWaitTime(); long timeUntilContinue = waitTime - now; synchronized(sigLock) {try { if(!halted.get()) { sigLock.wait(timeUntilContinue); } } catch (InterruptedException ignore) { } } 它是轮询任务的空闲等待代码，上面的sigLock.wait(timeUntilContinue)就对应了前面的Object.wait()。三、 jmap（Memory Map）和 jhat（Java Heap Analysis Tool）：jmap导出堆内存，然后使用jhat来进行分析，jmap语法格式如下：jmap [option] pid jmap [option] executable core jmap [option] [server-id@]remote-hostname-or-ip 如果运行在64位JVM上，可能需要指定-J-d64命令选项参数。jmap -permstat pid 打印进程的类加载器和类加载器加载的持久代对象信息，输出：类加载器名称、对象是否存活（不可靠）、对象地址、父类加载器、已加载的类大小等信息，如下图：使用jmap -heap pid查看进程堆内存使用情况，包括使用的GC算法、堆配置参数和各代中堆内存使用情况。比如下面的例子：root@ubuntu:/# jmap -heap 21711 Attaching to process ID 21711, please wait... Debugger attached successfully. Server compiler detected. JVM version is 20.10-b01 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 2067791872 (1972.0MB) NewSize = 1310720 (1.25MB) MaxNewSize = 17592186044415 MB OldSize = 5439488 (5.1875MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 21757952 (20.75MB) MaxPermSize = 85983232 (82.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 6422528 (6.125MB) used = 5445552 (5.1932830810546875MB) free = 976976 (0.9317169189453125MB) 84.78829520089286% used From Space: capacity = 131072 (0.125MB) used = 98304 (0.09375MB) free = 32768 (0.03125MB) 75.0% used To Space: capacity = 131072 (0.125MB) used = 0 (0.0MB) free = 131072 (0.125MB) 0.0% used PS Old Generation capacity = 35258368 (33.625MB) used = 4119544 (3.9287033081054688MB) free = 31138824 (29.69629669189453MB) 11.683876009235595% used PS Perm Generation capacity = 52428800 (50.0MB) used = 26075168 (24.867218017578125MB) free = 26353632 (25.132781982421875MB) 49.73443603515625% used .... 使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图，如果带上live则只统计活对象，如下：root@ubuntu:/# jmap -histo:live 21711 | more num #instances #bytes class name---------------------------------------------- 1: 38445 5597736 <constMethodKlass> 2: 38445 5237288 <methodKlass> 3: 3500 3749504 <constantPoolKlass> 4: 60858 3242600 <symbolKlass> 5: 3500 2715264 <instanceKlassKlass> 6: 2796 2131424 <constantPoolCacheKlass> 7: 5543 1317400 [I 8: 13714 1010768 [C 9: 4752 1003344 [B 10: 1225 639656 <methodDataKlass> 11: 14194 454208 java.lang.String 12: 3809 396136 java.lang.Class 13: 4979 311952 [S 14: 5598 287064 [[I 15: 3028 266464 java.lang.reflect.Method 16: 280 163520 <objArrayKlassKlass> 17: 4355 139360 java.util.HashMap$Entry 18: 1869 138568 [Ljava.util.HashMap$Entry; 19: 2443 97720 java.util.LinkedHashMap$Entry 20: 2072 82880 java.lang.ref.SoftReference 21: 1807 71528 [Ljava.lang.Object; 22: 2206 70592 java.lang.ref.WeakReference 23: 934 52304 java.util.LinkedHashMap 24: 871 48776 java.beans.MethodDescriptor 25: 1442 46144 java.util.concurrent.ConcurrentHashMap$HashEntry 26: 804 38592 java.util.HashMap 27: 948 37920 java.util.concurrent.ConcurrentHashMap$Segment 28: 1621 35696 [Ljava.lang.Class; 29: 1313 34880 [Ljava.lang.String; 30: 1396 33504 java.util.LinkedList$Entry 31: 462 33264 java.lang.reflect.Field 32: 1024 32768 java.util.Hashtable$Entry 33: 948 31440 [Ljava.util.concurrent.ConcurrentHashMap$HashEntry; class name是对象类型，说明如下：B byte C char D double F float I int J long Z boolean [ 数组，如[I表示int[] [L+类名 其他对象 还有一个很常用的情况是：用jmap把进程内存使用情况dump到文件中，再用jhat分析查看。jmap进行dump命令格式如下：jmap -dump:format=b,file=dumpFileName pid 我一样地对上面进程ID为21711进行Dump：root@ubuntu:/# jmap -dump:format=b,file=/tmp/dump.dat 21711 Dumping heap to /tmp/dump.dat ... Heap dump file created dump出来的文件可以用MAT、VisualVM等工具查看，这里用jhat查看：root@ubuntu:/# jhat -port 9998 /tmp/dump.dat Reading from /tmp/dump.dat... Dump file created Tue Jan 28 17:46:14 CST 2014Snapshot read, resolving... Resolving 132207 objects... Chasing references, expect 26 dots.......................... Eliminating duplicate references.......................... Snapshot resolved. Started HTTP server on port 9998Server is ready. 注意如果Dump文件太大，可能需要加上-J-Xmx512m这种参数指定最大堆内存，即jhat -J-Xmx512m -port 9998 /tmp/dump.dat。然后就可以在浏览器中输入主机地址:9998查看了：上面红线框出来的部分大家可以自己去摸索下，最后一项支持OQL（对象查询语言）。四、jstat（JVM统计监测工具）:看看各个区内存和GC的情况语法格式如下：jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ] vmid是Java虚拟机ID，在Linux/Unix系统上一般就是进程ID。interval是采样时间间隔。count是采样数目。比如下面输出的是GC信息，采样时间间隔为250ms，采样数为4：root@ubuntu:/# jstat -gc 21711 250 4 S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT 192.0 192.0 64.0 0.0 6144.0 1854.9 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649 192.0 192.0 64.0 0.0 6144.0 1972.2 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649 192.0 192.0 64.0 0.0 6144.0 1972.2 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649 192.0 192.0 64.0 0.0 6144.0 2109.7 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649 要明白上面各列的意义，先看JVM堆内存布局：可以看出：堆内存 = 年轻代 + 年老代 + 永久代 年轻代 = Eden区 + 两个Survivor区（From和To） 现在来解释各列含义：S0C、S1C、S0U、S1U：Survivor 0/1区容量（Capacity）和使用量（Used） EC、EU：Eden区容量和使用量 OC、OU：年老代容量和使用量 PC、PU：永久代容量和使用量 YGC、YGT：年轻代GC次数和GC耗时 FGC、FGCT：Full GC次数和Full GC耗时 GCT：GC总耗时 五、hprof（Heap/CPU Profiling Tool）：hprof能够展现CPU使用率，统计堆内存使用情况。语法格式如下：java -agentlib:hprof[=options] ToBeProfiledClass java -Xrunprof[:options] ToBeProfiledClass javac -J-agentlib:hprof[=options] ToBeProfiledClass 完整的命令选项如下：Option Name and Value Description Default --------------------- ----------- ------- heap=dump|sites|all heap profiling all cpu=samples|times|old CPU usage off monitor=y|n monitor contention n format=a|b text(txt) or binary output a file=<file> write data to file java.hprof[.txt] net=<host>:<port> send data over a socket off depth=<size> stack trace depth 4 interval=<ms> sample interval in ms 10 cutoff=<value> output cutoff point 0.0001 lineno=y|n line number in traces? y thread=y|n thread in traces? n doe=y|n dump on exit? y msa=y|n Solaris micro state accounting n force=y|n force output to <file> y verbose=y|n print messages about dumps y 来几个官方指南上的实例。CPU Usage Sampling Profiling(cpu=samples)的例子：java -agentlib:hprof=cpu=samples,interval=20,depth=3 Hello 上面每隔20毫秒采样CPU消耗信息，堆栈深度为3，生成的profile文件名称是java.hprof.txt，在当前目录。CPU Usage Times Profiling(cpu=times)的例子，它相对于CPU Usage Sampling Profile能够获得更加细粒度的CPU消耗信息，能够细到每个方法调用的开始和结束，它的实现使用了字节码注入技术（BCI）：javac -J-agentlib:hprof=cpu=times Hello.java Heap Allocation Profiling(heap=sites)的例子：javac -J-agentlib:hprof=heap=sites Hello.java Heap Dump(heap=dump)的例子，它比上面的Heap Allocation Profiling能生成更详细的Heap Dump信息：javac -J-agentlib:hprof=heap=dump Hello.java 虽然在JVM启动参数中加入-Xrunprof:heap=sites参数可以生成CPU/Heap Profile文件，但对JVM性能影响非常大，不建议在线上服务器环境使用
[scode type="share"]本文转载于：newx，学习一下。[/scode]在电子取证过程中，也会遇到提取PC版微信数据的情况，看雪、52破解和CSDN等网上的PC版微信数据库破解文章实在是太简略了，大多数只有结果没有过程。经过反复试验终于成功解密了数据库，现在把详细过程记录下来，希望大家不要继续在已经解决的问题上过度浪费时间，以便更投入地研究尚未解决的问题。通过查阅资料得知，与安卓手机版微信的7位密码不同，PC版微信的密码是32字节（64位），加密算法没有说明，但是可以通过OllyDbg工具从内存中获取到这个密码，然后通过一段C++代码进行解密。首先下载OllyDbg 2.01汉化版，我用的版本如下图所示：运行OllyDbg，然后运行PC版微信（需要下载客户端的，不是网页版）。先不要点击登录按钮。切换到Ollydbg界面：点击文件菜单，选择“附加”，在弹出的对话框中找到名称为WeChat的进程，其窗口名称为“登录”。然后点击“附加”。附加成功后OllyDbg开始加载，成功加载后可以看到最上面OllyDbg后面有WeChat.exe的字样：在查看菜单中选择“可执行模块”：找到名称为WeChatWin的模块，双击选中。为了方便观察，在窗口菜单中选择水平平铺。在CPU窗口标题栏可以看到“模块WeChatWin”字样。在插件中选择“StrFinder字符查找”中的“查找ASCII字符串”（注意如果下载的OllyDbg版本不对，可能没有相关插件，因此一定要找对版本），要稍微等一会儿，会出现搜索结果的窗口。在此窗口点击鼠标右键，选择“Find”，在搜索框中输入“DBFactory::encryptDB”。会自动定位在第一处，但我们需要的是第二处，即“encryptDB %s DBKey can’t be null”下面这一处。可以用鼠标点击滚动条向下，找到第二处，用鼠标双击此处。在CPU窗口中可以看到已经定位到了相应的位置。用鼠标点击滚动条向下翻。下面第六行应该是TEST EDX,EDX，就是用来比对密码的汇编语言代码。在最前面地址位置（本文中是0F9712BA）双击设置断点（设置断点成功则地址会被标红，而且可以在断点窗口中看到设置成功的断点）点击“运行”按钮（或者在调试菜单中选择“运行”），这时寄存器窗口中的EDX的值应该是00000000。切换到微信登录页面，点击登录，然后到手机端确认登录。这是OllyDbg界面中的数据不断滚动，直到EDX不再为全0并且各个窗口内容停止滚动为止。在EDX的值上面点击鼠标右键，在弹出的菜单里面选择“数据窗口中跟随”，则数据窗口中显示的就是EDX的内容。图示中从0B946A80（这个数值是变化的，不但每台电脑不同，每次调试也可能完全不同）到0B946A9F共32个字节就是微信的加密密码，本图中就是：“53E9BFB23B724195A2BC6EB5BFEB0610DC2164756B9B4279BA32157639A40BB1” 一共32个字节，共64位。得到这个之后，就可以关闭OllyDbg了，微信也会自动被关闭。接下来就是解密过程。在看雪、52破解等多个论坛中都有相关的C++源码，开始企图使用Dev-C++或者C-Free等轻量级IDE进行编译，也使用过Visual C++ 6.0绿色精简版，结果多次尝试出现各种错误，反复失败，最终不得已使用Visual Studio，并对代码进行了一定的修正，终于调试成功。正好Visual Studio 2019刚刚发布直接到官方网站下载了社区版。根据查到的资料，需要先安装openssl，为了省事直接下载了最新的Win64OpenSSL-1_1_1b，安装后发现各种报错，继续查找资料发现原来sqlcipher使用的是低版本的openssl，之后找到了一个Win64OpenSSL-1_0_2r也报错，最后发现还是官方这个直接解压缩的版本靠谱：https://www.openssl.org/source/openssl-1.0.2r.tar.gz把压缩包直接解压到任意目录，比如c:openssl-1.0.2r启动Visual Studio 2019社区版（估计Visual Studio 2008以后的都应该可以，懒得找就直接官网下载最新的吧）在启动界面右下方选择“创建新项目”滚动下拉条，在窗口中选择C++控制台应用：给项目随便起个名字，选择保存位置：然后点击“创建”，即可完成新项目创建。生成默认的Hello World代码：先要做好项目的基础配置，之前调试失败主要问题就出在这里了。在项目菜单中最下面选择项目属性“dewechat属性”（这个跟设置的项目名称一致）对话框最左上角的配置后面，可以选择配置的是Debug模式还是Release模式（Release模式不包含调试信息，编译完成的exe文件更小一些，但如果是自己用，这两个模式没有区别，配置了哪个，后面就要用哪个模式编译，否则会报错）先选择C/C++下面的“常规”选项：右边第一条是“附加包含目录”，点击右侧空白处。在下拉框里选择“编辑…”，在对话框中点击四个图标按钮最左侧的“新行”按钮，会生成一个空白行，点击右侧的“…”：在弹出的对话框里选择刚刚安装的openssl目录（本文是c:openssl-1.0.2r）中的include目录。设置完成后如下：然后选择左侧“链接器”下面的“常规”：在中间位置，有一个“附加库目录”，点击右侧空白处，选择openssl目录下的lib目录，设置完成后如下：最后点击链接器下面的“输入”：右侧最上面有“附加依赖项”，默认已经有一些系统库，点击右侧内容，选择“编辑…”这个没有增加新行的按钮，只能手工录入或者拷贝文件名进去，需要增加上图所示的两个库名称。设置完成后如下：现在所有的设置都OK了，可以把代码放进来编译了。由于太多网站转载，而且很多有错漏，已经搞不清原始代码是哪位大神写的了，其中有一些已经被废弃的代码，根据系统报错提示进行了替换，另外做了一个主要的变化就是之前的代码是把数据库名写在变量中，但由于需要解密很多库，为了灵活，改为输入参数的方法，即在运行时带参数运行或者根据提示输入需要解密的数据库文件名。using namespace std; #include <Windows.h> #include <iostream> #include <openssl/rand.h> #include <openssl/evp.h> #include <openssl/aes.h> #include <openssl/hmac.h> #undef _UNICODE #define SQLITE_FILE_HEADER "SQLite format 3" #define IV_SIZE 16 #define HMAC_SHA1_SIZE 20 #define KEY_SIZE 32 #define SL3SIGNLEN 20 #ifndef ANDROID_WECHAT #define DEFAULT_PAGESIZE 4096 //4048数据 + 16IV + 20 HMAC + 12 #define DEFAULT_ITER 64000 #else #define NO_USE_HMAC_SHA1 #define DEFAULT_PAGESIZE 1024 #define DEFAULT_ITER 4000 #endif //pc端密码是经过OllyDbg得到的32位pass。 unsigned char pass[] = { 0x53,0xE9,0xBF,0xB2,0x3B,0x72,0x41,0x95,0xA2,0xBC,0x6E,0xB5,0xBF,0xEB,0x06,0x10,0xDC,0x21,0x64,0x75,0x6B,0x9B,0x42,0x79,0xBA,0x32,0x15,0x76,0x39,0xA4,0x0B,0xB1 }; char dbfilename[50]; int Decryptdb(); int CheckKey(); int CheckAESKey(); int main(int argc, char* argv[]) { if (argc >= 2) //第二个参数argv[1]是文件名 strcpy_s(dbfilename, argv[1]); //复制 //没有提供文件名，则提示用户输入 else { cout << "请输入文件名:" << endl; cin >> dbfilename; } Decryptdb(); return 0; } int Decryptdb() { FILE* fpdb; fopen_s(&fpdb, dbfilename, "rb+"); if (!fpdb) { printf("打开文件错!"); getchar(); return 0; } fseek(fpdb, 0, SEEK_END); long nFileSize = ftell(fpdb); fseek(fpdb, 0, SEEK_SET); unsigned char* pDbBuffer = new unsigned char[nFileSize]; fread(pDbBuffer, 1, nFileSize, fpdb); fclose(fpdb); unsigned char salt[16] = { 0 }; memcpy(salt, pDbBuffer, 16); #ifndef NO_USE_HMAC_SHA1 unsigned char mac_salt[16] = { 0 }; memcpy(mac_salt, salt, 16); for (int i = 0; i < sizeof(salt); i++) { mac_salt[i] ^= 0x3a; } #endif int reserve = IV_SIZE; //校验码长度,PC端每4096字节有48字节 #ifndef NO_USE_HMAC_SHA1 reserve += HMAC_SHA1_SIZE; #endif reserve = ((reserve % AES_BLOCK_SIZE) == 0) ? reserve : ((reserve / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; unsigned char key[KEY_SIZE] = { 0 }; unsigned char mac_key[KEY_SIZE] = { 0 }; OpenSSL_add_all_algorithms(); PKCS5_PBKDF2_HMAC_SHA1((const char*)pass, sizeof(pass), salt, sizeof(salt), DEFAULT_ITER, sizeof(key), key); #ifndef NO_USE_HMAC_SHA1 PKCS5_PBKDF2_HMAC_SHA1((const char*)key, sizeof(key), mac_salt, sizeof(mac_salt), 2, sizeof(mac_key), mac_key); #endif unsigned char* pTemp = pDbBuffer; unsigned char pDecryptPerPageBuffer[DEFAULT_PAGESIZE]; int nPage = 1; int offset = 16; while (pTemp < pDbBuffer + nFileSize) { printf("解密数据页:%d/%d \n", nPage, nFileSize / DEFAULT_PAGESIZE); #ifndef NO_USE_HMAC_SHA1 unsigned char hash_mac[HMAC_SHA1_SIZE] = { 0 }; unsigned int hash_len = 0; HMAC_CTX hctx; HMAC_CTX_init(&hctx); HMAC_Init_ex(&hctx, mac_key, sizeof(mac_key), EVP_sha1(), NULL); HMAC_Update(&hctx, pTemp + offset, DEFAULT_PAGESIZE - reserve - offset + IV_SIZE); HMAC_Update(&hctx, (const unsigned char*)& nPage, sizeof(nPage)); HMAC_Final(&hctx, hash_mac, &hash_len); HMAC_CTX_cleanup(&hctx); if (0 != memcmp(hash_mac, pTemp + DEFAULT_PAGESIZE - reserve + IV_SIZE, sizeof(hash_mac))) { printf("\n 哈希值错误! \n"); getchar(); return 0; } #endif // if (nPage == 1) { memcpy(pDecryptPerPageBuffer, SQLITE_FILE_HEADER, offset); } EVP_CIPHER_CTX* ectx = EVP_CIPHER_CTX_new(); EVP_CipherInit_ex(ectx, EVP_get_cipherbyname("aes-256-cbc"), NULL, NULL, NULL, 0); EVP_CIPHER_CTX_set_padding(ectx, 0); EVP_CipherInit_ex(ectx, NULL, NULL, key, pTemp + (DEFAULT_PAGESIZE - reserve), 0); int nDecryptLen = 0; int nTotal = 0; EVP_CipherUpdate(ectx, pDecryptPerPageBuffer + offset, &nDecryptLen, pTemp + offset, DEFAULT_PAGESIZE - reserve - offset); nTotal = nDecryptLen; EVP_CipherFinal_ex(ectx, pDecryptPerPageBuffer + offset + nDecryptLen, &nDecryptLen); nTotal += nDecryptLen; EVP_CIPHER_CTX_free(ectx); memcpy(pDecryptPerPageBuffer + DEFAULT_PAGESIZE - reserve, pTemp + DEFAULT_PAGESIZE - reserve, reserve); char decFile[1024] = { 0 }; sprintf_s(decFile, "dec_%s", dbfilename); FILE * fp; fopen_s(&fp, decFile, "ab+"); { fwrite(pDecryptPerPageBuffer, 1, DEFAULT_PAGESIZE, fp); fclose(fp); } nPage++; offset = 0; pTemp += DEFAULT_PAGESIZE; } printf("\n 解密成功! \n"); return 0; } 将之前默认的代码全部清除，将以上代码拷贝进去，保存。然后在工具条栏中选择是Debug还是Release模式，是x86还是x64（需要跟之前配置匹配，如果选了没配置的模式会报错。测试发现几个选项没有太大区别，建议默认），之后点击“本地windows调试器”（或者按F5键），如果前面的步骤操作都正确，应该可以完成编译并自动运行，弹出一个命令行窗口，提示需要输入文件名：最下方显示了生成的exe文件路径，将这个文件拷贝到微信数据库所在的目录，一般是：C:UsersAdministratorDocumentsWeChat Files**Msg其中位置为需要解密的微信id，目录内容如下：如果要解密ChatMsg.db，则在命令行窗口输入指令dewechat ChatMsg.db回车即可。解密成功后，会在目录中生成de_ChatMsg.db，用sqlite数据库管理软件打开即可。本文主要是个验证过程，没有做什么突破工作，目前的解密只能算是半自动过程，密码算法部分的获得是下一步需要研究的内容，希望大家共同努力！
一、什么是Imagemagick？ImageMagick是一款免费开源的图片编辑软件。既可以通过命令行使用，也可以通过C/C++、Perl、Java、PHP、Python或Ruby调用库编程来完成。ImageMagic的主要精力集中在性能，减少bug以及提供稳定的API和ABI上。二、下载和安装这里以Windows为例使用16-bit在处理图片时比8-bit慢15%至50%，内存也为2倍。比如处理一张1024x768像素的图片8-bit要使用3.6M内存，16-bit要使用7.2M内存。这里我们选择下载官方推荐的文件，也就是第一个：ImageMagick-7.1.0-2-Q16-HDRI-x64-dll.exe然后安装：使用 magick --version 查看是否安装成功：三、使用如果很多子命令不能直接使用，则可以把他们当做magick的子命令使用，如：1、转换格式magick ImageMagick.jpg ImageMagick.png 表示把ImageMagick.jpg这个图片另存一份为ImageMagick.png，同时修改了图片名称和格式。2、合成gif这里把上面的安装截图拼成一个gif动图看看：magick ImageMagick-install-1.jpg ImageMagick-install-2.jpg ImageMagick-install-3.jpg ImageMagick-install.gif 3、调整图片大小按比例改变magick ImageMagick.png -resize 200% ImageMagick-2.png magick convert ImageMagick.png -resize 200% ImageMagick-2.png 改变前的文件大小：改变后的文件大小：下面的一些方法留着大家自己试试，这里就不传结果图片了。比如，图片宽扩展为原来的2倍，高缩小为原来的一半magick convert ImageMagick.png -resize 200x50% ImageMagick-3.png magick convert ImageMagick.png -resize 200%x50% ImageMagick-4.png 宽调整为100，高按原来图片宽高比例跟着调整convert -resize 100 ImageMagick.png ImageMagick-5.png 高调整为200，宽按原来图片宽高比例跟着调整convert -resize x200 ImageMagick.png ImageMagick-6.png 4、移除图片内嵌的所有配置文件magick convert -strip ImageMagick.jpg 5、裁剪图片crop参数可以把一副图像分成若干块大小一样的图片magick ImageMagick.jpg -crop 500x500 ImageMagick-7.jpg 例如，原图片尺寸为1920x1200，所以可以分割出12块图片，注意如果尺寸不是目标图片的整数倍，那么右边缘和下边缘的一部分图片就用实际尺寸在原始图像上裁剪一张指定尺寸的小图magick ImageMagick.jpg -crop 600x450+300+600 ImageMagick-8.jpg 600x450是宽乘高，+300+600是横纵坐标6、图片取反magick convert ImageMagick.jpg -negate ImageMagick-canny.jpg 7、压缩图片将图片质量降为原来的10%（即压缩掉了90%），取值范围1 ( 最低的图像质量和最高压缩率) 到100 ( 最高的图像质量和最低压缩率)，默认值根据输出格式有75、92、100，选项适用于JPEG / MIFF / PNG.magick convert -quality 80 ImageMagick.jpg ImageMagick-9.jpg 实例：生成缩略图:-resize，定义输出的缩略图尺寸；-quality 70，降低缩略图的质量为70%；-strip：让缩略图移除图片内嵌的所有配置文件，注释等信息，以减小文件大小。magick convert -resize 100x200 -quality 70 -strip ImageMagick.jpg ImageMagick-10.jpg 8、给图片加边框设置边框颜色为蓝色（也可以用rgb(0,0,255)或者rgb(0%,0%,100%)代替），宽的边框和高的边框分别为宽的5%、高的5%，也就是说，图片的高和宽都增大了10%magick ImageMagick.jpg -bordercolor blue -border 5% ImageMagick-11.jpg 9、滤镜magick convert monochrome.jpg -monochrome monochrome_example.jpg magick convert charcoal.jpg -charcoal 1.2 charcoal _example.jpg -monochrome没有相关的配置选项；但是-charcoal需要设置一个相关因子，1左右能实现类似炭笔绘画的效果。magick convert a.jpg -edge 3 edge.jpg magick convert a.jpg -colors 2 color.jpg 减少为2种颜色，这些选项也可以一起使用。10、边缘检测magick convert a.jpg -canny 1 canny.jpg 使用canny算法，带粗粒度参数。图像取反的话就很好看了：magick convert a.jpg -canny 1 -negate canny.jpg
Windows 10附带捆绑了许多过时的软件，即使我们系统重装，这些自带软件都是无法避免的，有一个名为Windows 10 Debloater的开源工具，它需要运行PowerShell脚本，但提供了图形界面，删除这些软件非常方便。目前，Windows10Debloater在Github上已经标星 6K，累计分支 737 个。（Github地址：https://github.com/Sycnex/Windows10Debloater）下面就和大家介绍一下Windows10Debloater的使用方法：- 步骤1、下载并解压Windows 10 Debloater首先你需要在Github上下载该脚本，如下，点击【下载】按钮之后，单击选择【下载Zip】现在，不出意外的话，你现在的下载目录里已经有一个名为Windows10Debloater-master.zip的ZIP文件。然后你还需要将它解压，解压后得到如下文件夹：- 步骤2、使用PowerShell运行Windows10DebloaterGUI.ps1打开Windows10Debloater-master文件夹，右键单击名为Windows10DebloaterGUI.ps1的文件，选择【使用Powershell运行】：接下来会跳出一个脚本运行警告，你需要选择【是】，也就是输入【Y】允许工具继续运行。- 步骤3、从Windows 10 PC上删除所有过时的软件完成以上操作后，你就会看到以下窗口，单击【Remove All Bloatware】然后系统就会立即开始卸载在PC或设备上找到的bloatware应用程序。你还可以从后台的PowerShell窗口，查看脚本运行的速度。最后我们可以看到Windows 10 Debloater会删除以下应用。当然，并非所有人都想删除这些软件，有一些你可能还想留着，Windows 10 Debloater是允许你还原删除的软件，你只需要重新运行，单击【Revert Changes】按钮即可：需要提醒你的是，虽然你不能从用户界面选择哪些应用程序要删除，哪些应用程序要保留，但是你可以打开编辑应用程序的脚本文件夹中的Debloat Windows文件，并从列表中删除你想保留的应用程序。