天津市某文化馆网站服务器遭到病毒袭击。网站所在硬盘全盘空间占满,导致网站瘫痪。
如下是挂了木马的网页代码:
经鸿萌工程师确认,这台网站服务器所中为最新的VBS病毒。这种病毒会感染网站文件,所有网站静态.html被挂了无限的代码,直到将整个分区完全占满。工程师看到客户存放网站文件的F盘500G已经没有一丝剩余空间。同时该病毒复制大量病毒代码到可执行文件中,只要计算机调用文件,即会传染更多文件。病毒进程如下:
此次所遇到的病毒比较特殊,由于客户发现时间较晚,病毒已经把系统盘和网站所在分区硬盘空间占满,系统运行缓慢,没有任何缓存空间。致使无法使用杀毒软件或者专杀工具进行查杀。由于网站配置比较复杂,所有网页又被挂马感染,解决起来比较复杂。客户不想重做系统,于是我公司为其量身定做了个性化解决方案。
首先,将网站程序、服务和病毒进程关闭,使病毒无法继续运行。
其次,将中毒的系统和网站程序做一个全盘的镜像,保存原始数据,以备不测。
然后工程师通过自定义批处理工具和手工双重查杀,利用自定义代码清除的批处理命令,将网站中数万个静态网页上面挂的病毒代码清理完毕,历时三天三夜的查杀,终于彻底清除了病毒。
最后重新配置网站系统,将网站恢复运营。
少小伙伴在电脑应用的时候都会发现:通常自己只打开一个网页浏览,但是有的时候却感觉电脑运行不顺畅,打开资源管理器一看,处理器占用率不低,甚至会出现多个网页的线程……对于这个现象多年来也没人给一个合理的解释,不过最近微软终于主动现身解开了这个谜题。
很多人遇到这种情况,都会以为自己中了病毒,实际上并非如此。最近微软官方在一篇技术文章中,说明了其实这是现代浏览器采用了多线程的架构所建构。简单而言,当你运行一个浏览器的时候,这个浏览器其实并非是单进程软件,而是采用了多进程的架构,浏览器在运行的时候,会调动不同的资源,但是在任务管理器的后台上,都会显示为浏览器的图标,这就是浏览器为什么运行后会有多个后台进程的真正原因。
微软详细解释了自家Edge浏览器的多进程架构,同样的原理也适用于目前世界第一大浏览器谷歌的Chrome浏览器上。微软表示,浏览器采用多进程架构,浏览器在工作时主要被分为几个不同的行程。
首先是浏览,这是主要的进程,负责视窗窗口和选项管理,控制浏览器的地址栏、前进/ 后退按钮等框架、且要处理网络请求和档案存取。
其次是计算,通过执行网站提供的程式码,来控制一个网页的呈现,能够处理超文字标记语言(HTML)、级联样式表(CSS)、JavaScript 和图像等内容。
然后是GPU硬件加速的计算,这部分负责与图形硬体相关的所有任务,比如加速图形运算、并将处理器结果输出到显示器上。此外还有实用功能的进程,这部分负责了影片播放、网络服务、资料解码、以及集合管理,微软和谷歌的浏览器可借此控制、管理、协调系统资源。
此外进程中还有附加程式,这部分负责了对各个附加程式的管理,每个进程的资源使用情况、以及同主进程/计算进程的沟通。最后还有崩溃处理的进程,如果浏览器发生崩溃,Crashpad Handler 能够捕获异常、并将错误报告传递,以查找问题和修复故障。
必须要说的是,出于可靠性和安全性的考虑,即便是同一网页上的不同元素,也可能被分配了单独的进程。这样,即使是不慎被恶意软体利用了一个计算进程中的安全漏洞,也可避免其影响另一个行程。
所以综合来讲,浏览器虽然只是单独的一个软件,但要正常使用浏览器,那么就需要电脑分配多个进程给它,甚至有的时候在一些复杂的网页上,电脑的计算要耗费不少的性能,所以还会导致浏览器的占用率比较高,比如说一些可播放视频的网站。这也是为什么我们在后台看到一个浏览器会有这么多进程的原因。
从好处上来看,多进程的浏览器提升了整体的安全性,防止了不同功能在同一个进程中的串访,而且即使出现了一些故障,比如说网页崩溃,也只会影响其中一个进程,对浏览器的稳定性也有很大的重要。
通过这个释疑,以后大家打开浏览器如果再看到这么多的后台进程,大家也就不用担心了,这是浏览器努力为大家服务的表现,而且在大多数时候后台进程虽多,但是处理器资源占用并不高,除非你玩什么网页游戏或者通过网页观看视频!
产服务内存高问题
(1)根据cat监控,获取“计算中心”中的热点方法,进行REVIEW,修正了部分可能会导致内存泄露的方法。并进行了观察。
(2)通过VisualVM监控,定位到部分耗时较久的操作DB热点方法,通过增加索引等方式,把查询性能控制在毫秒级。
(3)dump“计算中心”的内存镜像,通过MAT等工具观察各个对象在堆空间中所占用的内存大小、类实例数量、对象引用关系。
结论:通过以上三点,未解决和定位“计算中心”内存高问题。由此可以认为,“计算中心”的内存占用问题与代码无关。
通过java ps| aux java 查看,“计算中心”服务实际占用的内存在4.9G左右,超过了JVM堆内存设置的大小但并未出现OOM,业务正常运行。通过free -g命令,可以发现buff/cache,3个g左右。centos中内存的分配是buff/cache + free + used=物理内存大小,系统分配给临时文件系统的大小默认是用掉一半的物理内存,这样会造成buff/cache很大,而free很小。最终结论可能为服务内存没有释放使用了buff/cache。导致服务内存占用很高。
结论:和SRE沟通实际重启服务后,内存使用率立刻降低,但是buff/cache的大小没有变化。由此可以认为,“计算中心”的内存占用问题与系统缓存无关。
1、通过VisualVM监控生产环境computing内存使用情况得出,在服务内存占用4.8g的情况下,堆内存(新生代 + 老年代)正常GC,在增长到2g左右会GC到300~500m,Matespace仅使用了120m左右。检查了生产JVM参数。项目启动参数没有配置:-XX:MaxDirectMemorySize,来指定最大的堆外内存大小。这个阈值不配置的话,默认占用-Xmx相同的内存。在堆内内存正常的情况下,怀疑是堆外内存占用了大部分内存,导致服务内存占用很高。
结论:和SRE沟通,在生产环境找了两台计算中心服务实例配置 -XX:MaxDirectMemorySize 参数后实际观察后,仍未解决“计算中心”内存高问题。由此可以认为,“计算中心”的内存占用问题与堆外内存无关。
2、在发现-XX:MaxDirectMemorySize 指定堆外内存大小的参数没有配置后。我检查了“计算中心”服务的启动参数并且和之前生产环境的服务进行了对比,发现了以下问题。
1)生产及测试环境JVM参数配置混乱,同一应用不同实例多套启动参数配置。
2)服务启动参数,未区分JDK版本。如:JDK1.7、JDK1.8参数混用。
3)生产服务根据模板部署,导致必要JVM参数未配置,部分参数配置不需要、不合理。
4)不同类型的应用,采用统一的启动参数配置,不具有针对性。在以上问题的基础上,基于目前生产环境各项目统一使用的"CMS垃圾回收器"进行参数调整。针对计算中心的JDK版本(1.8),出了一套JVM配置方案。并在生产服务器调整后重启观察。
结论:“计算中心”生产环境服务,在运行一段时间后,仍出现内存占用高问题。由此可以认为,“计算中心”的内存占用问题与不同JDK版本的参数混用问题无关。
3、经调研,逐渐被淘汰的垃圾回收器比如ParallelOldGC和CMS,只要JVM申请过的内存,即使发生了GC回收了很多内存空间,JVM也不会把这些内存归还给操作系统。这就会导致top命令中看到的RSS(进程RAM中实际保存的总内存)只会越来越高,而且一般都会超过Xmx的值。JDK1.9以后。默认的垃圾回收器已经选择了G1。
G1相比CMS有更清晰的优势:
1)CMS采用"标记-清理"算法,所以它不能压缩,最终导致内存碎片化问题。而G1采用了复制算法,它通过把对象从若干个Region(独立区域)拷贝到新的Region(独立区域)过程中,执行了压缩处理,垃圾回收后会整合空间,无内存碎片。
2)在G1中,堆是由Region(独立区域)组成的,因此碎片化问题比CMS肯定要少的多。而且,当碎片化出现的时候,它只影响特定的Region(独立区域),而不是影响整个堆中的老年代。
3)而且CMS必须扫描整个堆来确认存活对象,所以,长时间停顿是非常常见的,无法预测停顿时间。而G1的停顿时间取决于收集的Region(独立区域)集合数量,在指定时间内只回收部分价值最大的空间,而不是整个堆的大小,所以相比起CMS,长时间停顿要少很多,可控很多。
4)G1选回收阶段不会产生“浮动垃圾”,由于只回收部分Region(独立区域),所以STW(stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起)时间我们可控,所以不需要与用户线程并发争抢CPU资源。而CMS并发清理需要占据一部分的CPU,会降低吞吐量。G1由于STW,所以不会产生"浮动垃圾",CMS在并发清理阶段会产生的无法回收的垃圾。
因此在以下场景下G1更适合:
1)服务端多核CPU、JVM内存占用较大的应用。
2)应用在运行过程中会产生大量内存碎片、需要经常压缩空间。
3)想要更可控、可预期的GC停顿周期;防止高并发下应用雪崩现象。
结论:将”计算中心“使用的垃圾回收机制升级为G1,并增加G1相关的优化内存的参数,在生产服务器进行观察一周后发现服务内存始终稳定在了3.3G左右,业务处理性能稳定,成功解决了“计算中心”服务占用内存较高的问题,提升了系统的可用性,无需通过增加物理资源来提升服务整体性能。
计算中心“生产全部服务实例部署的服务器,使用的是JDK1.8,JDK1.8支持G1垃圾回收器,故将服务启动参数进行统一调整:
1)原参数(主要问题:使用CMS版本,JDK1.7,1.8参数混用,未指定堆外内存大小)
/opt/java/jdk1.8.0_102/bin/java -Dapp.home=${APP_HOME} -Dspring.profiles.active=prd -Dserver.port=${SERVER_PORT} -server -Xms4G -Xmx4G -Xmn2g -Xss256k -XX:PermSize=128m -XX:MaxPermSize=512m -Djava.awt.headless=true -Dfile.encoding=utf-8 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:AutoBoxCacheMax=20000 -XX:-OmitStackTraceInFastThrow -XX:ErrorFile=${APP_HOME}/logs/hs_err_%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${APP_HOME}/logs/ -Xloggc:${APP_HOME}/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -jar ${APP_HOME}/webapps/${JAR_NAME} ${SERVER_PORT}"
2)新参数(使用G1做为垃圾回收器)
/opt/java/jdk1.8.0_102/bin/java -Dapp.home=${APP_HOME} -Dspring.profiles.active=prd -Dserver.port=${SERVER_PORT} -server -Xms4g -Xmx4g -Xss256k -XX:NewSize=512m -XX:MaxNewSize=512m -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=40 -XX:G1HeapRegionSize=8m -XX:+ExplicitGCInvokesConcurrent -XX:ParallelGCThreads=4 -Dsun.rmi.dgc.server.gcInterval=36000000-Dsun.rmi.dgc.client.gcInterval=36000000-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=256m -XX:MaxDirectMemorySize=512m -XX:GCTimeRatio=19 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30 -XX:ErrorFile=${APP_HOME}/logs/hs_err_%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${APP_HOME}/logs/ -Xloggc:${APP_HOME}/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -jar ${APP_HOME}/webapps/${JAR_NAME} ${SERVER_PORT}"
注:不同服务器环境,不同容器,脚本配置各不相同,要在对应脚本的基础上进行针对性升级。
实际占用内存大小(参数):-XX:MaxPermSize(非堆) + -Xmx(堆) + -Xss(栈) + -XX:MaxDirectMemorySize(堆外)
实际占用内存大小(参数):-XX:MaxMateSpaceSize(堆外) + -Xmx(堆) + -Xss(栈) + -XX:MaxDirectMemorySize(堆外)
1、什么时候触发Minor GC
2、触发Minor GC 的过程
3、Full GC 的过程
1、新创建的对象一般会被分配在新生代中。常用的新生代的垃圾回收器是 ParNew 垃圾回收器,它按照 8:1:1 将新生代分成 Eden 区,以及两个 Survivor 区。创建的对象将 Eden 区全部挤满,这个对象就是「挤满新生代的最后一个对象」。此时,Minor GC 就触发了。
2、在正式 Minor GC 前,JVM 会先检查新生代中对象,是比老年代中剩余空间大还是小。Minor GC 之后 Survivor 区放不下剩余对象,这些对象就要进入到老年代,所以要提前检查老年代是不是够用。
3、老年代剩余空间大于新生代中的对象大小,那就直接 Minor GC,GC 完 survivor 不够放,老年代也绝对够放。老年代剩余空间小于新生代中的对象大小,这时候就要进入老年代空间分配担保规则。
4、老年代空间分配担保规则:如果老年代中剩余空间大小,大于历次 Minor GC 之后剩余对象的大小,那就允许进行 Minor GC。因为从概率上来说,以前的放的下,这次的也应该放的下。那就有两种情况:
紧接上一节 Full GC 之后,老年代任然放不下剩余对象,就只能 OOM。未开启老年代分配担保机制,且一次 Full GC 后,老年代任然放不下剩余对象,也只能 OOM。开启老年代分配担保机制,但是担保不通过,一次 Full GC 后,老年代任然放不下剩余对象,也是能 OOM。注:
作者: zhfeat
出处:https://www.cnblogs.com/zhfeat/p/13261543.html
*请认真填写需求信息,我们会在24小时内与您取得联系。