java内存回收需要了解的知识
你是否有过这样的经历,跑得好好的Java进程,突然就瘫痪了?多数Java进程瘫痪的原因可以从java虚拟机层面找到原因。
1、什么情况下会执行gc
为了了解我们的系统为什么会不停fgc,我们需要先了解一下系统什么情况下会gc。在jvm层面,当我们new一个对象的时候,jvm会先在堆区分配对象需要的内存,这个时候如果内存不够的话,就需要gc了、gc的返回结果就是对象的空间地址。jvm会先进行ygc,也就是我们通常说的标记复制,如果ygc之后依然申请不到空间,就会进行fgc了。同理,如果fgc之后依然没有足够的空间,就会循环的进行fgc,直到申请到足够的空间。
2、导致不停的fgc的原因
如上文所讲,fgc有可能发生在你的每一行代码。如果fgc之后依然没有足够的空间,就会不停的fgc,直到申请到足够的空间。同时JVM会限制在抛出OutOfMemory错误之前在GC中花费的VM时间的比例。系统频繁FGC大致有五种情况:
内存泄漏
请求处理变慢导致同时申请内存的线程太多
metaspace 耗尽
常量池将堆区占满
堆外内存耗尽
1w,正常情况下处理一个请求的时间是1ms,那同一时刻并行的请求数量仅为10。如果性能发生抖动,每个请求处理的时间增加到100ms,那同一时刻并行的请求数量就会增加到100个。每个线程在处理请求的时候都会new一些对象出来,长时间存活的线程会造成类似内存泄漏的效果,将系统的内存耗尽。同时fgc也会加剧系统性能的开销,使系统变得更慢,产生雪崩。
如何让系统fgc之后仍然能活下来?
1.杜绝内存泄漏
内存泄漏造成系统瘫痪的频率很高,有些系统定时从数据库拉取配置信息缓存到集合中,但是set不小心写成了list,最终在新增元素的时候内存溢出了。养成良好的编程习惯,多关注些细节,就能避免很多未知的问题。
2.并发限制:防止系统被撑死
每台服务器都有并行处理请求的上限,不管请求处理的多快,超过上限之后就会被撑死,对高并发的请求做好并发数限制是保持系统稳定的必要条件。需要注意的是,有一些系统在拒绝过多的请求时,也会做一些降级逻辑,降级逻辑也是有性能开销的,同样需要做并发限制,如果降级的请求超过并发限制,将不进行降级逻辑直接抛出异常。我们可使用的限流组件有很多,推荐我们阿里自研的Sentinel 和 Netflix开源的Hystrix。
3.自适应限流:防止系统被摸死
我们需要自适应限流有两个原因:
a. 每台服务器所处的环境是不一样的
有些服务器和离线计算的vm混部在一起,有些部署在实体机,有些部署在新老型号的机器上,每台服务器能承受的qps并不完全一样。统一配置分布式系统中每台服务器限流阀值,要么发挥不出每台服务器应有的作用,要么在高qps的情况下一些比较慢的服务器宕机,所以用服务器作为限流粒度是最合适的。
b.设置了正确的限流阀值,也可能被摸死
当单机承受的QPS 6~20倍于限流的流量时,拒绝一次请求的开销就无法忽略不记了。譬如春晚活动有些系统设置了正确的限流也被6~20倍于限流的流量冲垮。这种死法称为被摸死。应对这种情况,我们可以做的是在受到6~20倍的大流量时,动态减少限流的阀值。比如系统最开始接受1000qps,5000的拒绝流量过来会把系统摸死,这个时候我们调整系统的阀值,限流设置到100,被摸死的阀值就可以高一些,这样就算有6000个请求进来,我们系统也可以保证活下来。
4.异常流量监控:防止长尾请求拖垮系统
我们盯系统监控的时候通常会关注99分位的数据,但如果设置了合理的限流,系统依然被流量打挂,就要从那百分之一的长尾数据入手了。有些长尾数据对系统的影响会非常大。想象如果一个put请求传过来几十兆的数据,对java是极为不友好的,很有可能产生fgc,让请求变慢,导致一系列问题。 总之,磨刀不误砍柴工,当我们的系统因为fgc一次又一次重启的时候,不如花时间了解下系统产生性能问题的原因,将产生问题的那根针拔掉,晚上睡个安稳觉,白天更加充满活力的挖新坑。希望每个程序员手里都是一个稳定的系统。
java内存模型图
GC流程图
参考网址: https://hllvm-group.iteye.com/group/wiki/?category_id=301
java内存回收需要了解的知识的更多相关文章
- Java内存回收 - 落日之心的日志 - 网易博客
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- java 内存回收(GC)的方式
java内存的管理其实就是对象内存的管理,其中包括对象的分配和释放 对应程序员来说分配对象使用new关键字,而释放一个对象只需要让它等于null,让程序不能再访问这个对象,这时对象是不可达的,GC负责 ...
- Java内存回收机制
在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C/C++直接操作内存的危险.但是,也正 ...
- 图解Java内存回收机制
在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C/C++直接操作内存的危险.但是,也正 ...
- Java内存回收(垃圾回收)机制总结
一.背景: Java程序员编写程序时,对于新建的对象,当不再需要此对象时,不必去释放这个对象所占用的空间,这个工作是由Java虚拟机自己完成的 ,即内存回收或垃圾回收. 二.如何知道一个对象所占用的空 ...
- 【垃圾回收】Java内存回收实践经验 防止内存报警
jdk6和7服务器端(-server) 默认的新生代的垃圾回收器为:PS Scavenge,老年代默认的垃圾回收器为:PS MarkSweep 目前项目使用了jdk7,tomcat7,经常出现内存堆使 ...
- Java内存回收机制基础[转]
原文链接:http://blog.jobbole.com/37273/ 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了J ...
- 【朝花夕拾】Android性能篇之(三)Java内存回收
在上一篇日志([朝花夕拾]Android性能篇之(二)Java内存分配)中有讲到,JVM内存由程序计数器.虚拟机栈.本地方法栈.GC堆,方法区五个部分组成.其中GC堆是一块多线程的共享区域,它存在的作 ...
- Java 内存回收机制——GC机制
一.Java GC 概念说明 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾 ...
随机推荐
- vue.js 常用指令用法
v-if v-if指令可以完全根据表达式的值在DOM中生成或移除一个元素. 如果v-if表达式赋值为false,那么对应的元素就会从DOM中移除: 否则,对应元素的一个克隆将被重新插入DOM中,代码如 ...
- E. The Contest ( 简单DP || 思维 + 贪心)
传送门 题意: 有 n 个数 (1 ~ n) 分给了三个人 a, b, c: 其中 a 有 k1 个, b 有 k2 个, c 有 k3 个. 现在问最少需要多少操作,使得 a 中所有数 是 1 ~ ...
- idea快捷方式2
IntelliJ Idea 常用快捷键列表 Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Sh ...
- 系统信息的管理函数API
1.Windows系统信息 1.1获取系统版本: BOOL WINAPI GetVersionEx( __in_out LPOSVERSIONINFO lpVersionInfo ); lpVer ...
- MySQL数据分析—(4)关系数据库的三个逻辑框架
(一)前面课程逻辑梳理 任何一门数据的软件也好,数据构架也好,或者说是数据学科也好,最终都是要解决实际问题的,大家说是不是? 前面jacky讲为什么要引入数据库的时候,举了一个案例,大家还记的吗?大家 ...
- 2019-2020 ICPC, NERC, Northern Eurasia Finals (Unrated, Online Mirror, ICPC Rules, Teams Preferred)
这是一场三人组队赛来的,单人带电子模板不限时单挑试一下.按照难度排序. B - Balls of Buma 题意:玩祖玛,射入任意颜色的球一个,当某段长度变长了且长度变长后>=3则这段就会消除, ...
- 启动Docker后台容器,测试运行Hello-world
1.使用docker run hello-world命令运行测试hello-world镜像,如下: 2.run 命令都干了什么?如下图: 3.为什么Docker比vm快?
- 营销H5项目-BugList+解决方案+方法
作者会持续更新,后续会整合SF.gg上 其他小伙伴整理的资料 动态改变微信title var $body = $('body'); document.title = '五班老同学(35)'; var ...
- AtomicInteger原理
AtomicInteger的原理 java的并发原子包里面提供了很多可以进行原子操作的类,比如: AtomicInteger AtomicBoolean AtomicLong AtomicRefere ...
- pwn学习日记Day13 《程序员的自我修养》读书笔记
重定位就是把程序的逻辑地址空间变换成内存中的实际物理地址空间的过程.它是实现多道程序在内存中同时运行的基础.重定位有两种,分别是动态重定位与静态重定位. 静态重定位:即在程序装入内存的过程中完成,是指 ...