欢迎大家关注 github.com/hsfxuebao/j… ,希望对大家有所帮助,要是觉得可以的话麻烦给点一下Star哈
1.亿级流量电商
设置的jvm参数为:
-Xms3G -Xmx3G -Xss1M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M
JVM内存具体分配:
面试题:对JVM调优,让其几乎不发生Full GC?
由于在major GC时,部分对象还是有引用存在的,所以会进入S1或S0;
对象动态年龄判断(一批对象的总大小大于S1内存大小的50%(-XX:TargetSurvivorRatio可以指定)),那么大于等于这批对象年龄的最大值的对象就可以进入老年代,老年代被占满触发Full GC;
此时需要调整jvm参数如下:设置年轻代大小为2G
-Xms3G -Xmx3G -Xmn2G -Xss1M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M
2.12306网站
12306遭遇春节大规模抢票应该如何支撑?
- 12306应该是中国并发量最高的秒杀网站,号称并发量100W最高
- CDN->LVS->NGINX->业务系统->每台机器1W并发 100台机器
- 普通电商下单->下单系统->订单系统(IO)减库存->等待用户付款
- 12306的一种可能模型:下单->减库存和订单(redis kafka)同时异步进行->等付款->减库存,最后还会把压力压到一台服务器
- 分布式本地库存+单独服务器做库存均衡
- 大流量的处理方法:分而治之
1.怎么得到一个事务会消耗多少内存?
- 弄一台机器,看能承受多少TPS?是不是达到目标?扩容或调优
- 用压测来确定
3.案例汇总
- 线程池运用不当产生OOM问题
- tomcat http-header-size设置过大导致OOM
Java tomcat max-http-header-size配置导致的oom
3. lambda 表达式导致方法区溢出问题(MethodArea / Perm Metaspace)
设置JVM参数:-XX:MaxMetaspaceSize=9m -XX:+PrintGCDetails
public class LambdaGC {
public static void main(String[] args) {
for (; ; ) {
I i = C::n;
}
}
public static interface I {
void m();
}
public static class C {
static void n() {
System.out.println("hello");
}
}
}
运行结果:
4.直接内存溢出问题(少见)
《深入理解Java虚拟机》P59,使用Unsafe分配直接内存,或者使用NIO的问题
5.栈溢出问题
-Xss设定太小
6.下面两段代码,哪一种是更优的写法
Object o = null;
for(int i =0; i < 100; i++){
o = new Object();
}
// 更优
for(int i =0; i < 100; i++){
Object o = new Object();
}
// 需要在栈上一直分配o
7.重写finalize引发频繁GC
小米云,HBase同步系统,系统通过nginx访问超时报警,最后排查C++程序员重写finalize引发频繁GC问题
8.一个系统内存使用率不超过10%,但是观察GC日志,发现FGC总是频繁产生,什么引起?
System.gc()
9.有一个50万PV的资料类网站(从磁盘提取文档到内存)原服务器32位,1.5G
的堆,用户反馈网站比较缓慢,因此公司决定升级,新的服务器为64位,16G
的堆内存,结果用户反馈卡顿十分严重,反而比以前效率更低了
① 为什么原网站慢?
很多用户浏览数据,很多数据load到内存,内存不足,频繁GC,STW长,响应时间变慢
② 为什么会更卡顿?
内存越大,FGC时间越长
③ 咋办?PS -> PN + CMS 或者 G1
四.一个案例理解常用工具
-
测试代码:
package com.mashibing.jvm.gc; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * 从数据库中读取信用数据,套用模型,并把结果进行记录和传输 */ public class T15_FullGC_Problem01 { private static class CardInfo { BigDecimal price = new BigDecimal(0.0); String name = "张三"; int age = 5; Date birthdate = new Date(); public void m() {} } private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50, new ThreadPoolExecutor.DiscardOldestPolicy()); public static void main(String[] args) throws Exception { executor.setMaximumPoolSize(50); for (;;){ modelFit(); Thread.sleep(100); } } private static void modelFit(){ List<CardInfo> taskList = getAllCardInfo(); taskList.forEach(info -> { // do something executor.scheduleWithFixedDelay(() -> { //do sth with info info.m(); }, 2, 3, TimeUnit.SECONDS); }); } private static List<CardInfo> getAllCardInfo(){ List<CardInfo> taskList = new ArrayList<>(); for (int i = 0; i < 100; i++) { CardInfo ci = new CardInfo(); taskList.add(ci); } return taskList; } } -
java -Xms200M -Xmx200M -XX:+PrintGC com.mashibing.jvm.gc.T15_FullGC_Problem01
-
一般是运维团队首先受到报警信息(CPU Memory)
-
top命令观察到问题:内存不断增长 CPU占用率居高不下
-
top -Hp 观察进程中的线程,哪个线程CPU和内存占比高
-
jps定位具体java进程
jstack 定位线程状况,重点关注:WAITING BLOCKED
eg.
waiting on <0x0000000088ca3310> (a java.lang.Object)
假如有一个进程中100个线程,很多线程都在waiting on ,一定要找到是哪个线程持有这把锁
怎么找?搜索jstack dump的信息,找 ,看哪个线程持有这把锁RUNNABLE
作业:1:写一个死锁程序,用jstack观察 2 :写一个程序,一个线程持有锁不释放,其他线程等待 -
为什么阿里规范里规定,线程的名称(尤其是线程池)都要写有意义的名称
怎么样自定义线程池里的线程名称?(自定义ThreadFactory) -
jinfo pid
-
jstat -gc 动态观察gc情况 / 阅读GC日志发现频繁GC / arthas观察 / jconsole/jvisualVM/ Jprofiler(最好用)
jstat -gc 4655 500 : 每个500个毫秒打印GC的情况
如果面试官问你是怎么定位OOM问题的?如果你回答用图形界面(错误)
1:已经上线的系统不用图形界面用什么?(cmdline arthas)
2:图形界面到底用在什么地方?测试!测试的时候进行监控!(压测观察) -
jmap - histo 4655 | head -20,查找有多少对象产生
-
jmap -dump:format=b,file=xxx pid :
线上系统,内存特别大,jmap执行期间会对进程产生很大影响,甚至卡顿(电商不适合)
1:设定了参数HeapDump,OOM的时候会自动产生堆转储文件(不是很专业,因为多有监控,内存增长就会报警)
2:<font color='red'>很多服务器备份(高可用),停掉这台服务器对其他服务器不影响</font>
3:在线定位(一般小点儿公司用不到)
4:在测试环境中压测(产生类似内存增长问题,在堆还不是很大的时候进行转储)
12. java -Xms20M -Xmx20M -XX:+UseParallelGC -XX:+HeapDumpOnOutOfMemoryError com.mashibing.jvm.gc.T15_FullGC_Problem01
-
使用MAT / jhat /jvisualvm 进行dump文件分析
www.cnblogs.com/baihuitests…
jhat -J-mx512M xxx.dump
http://192.168.17.11:7000
拉到最后:找到对应链接
可以使用OQL查找特定问题对象 -
找到代码的问题