大厂秋招面经,特意分享大家

阿里

Java

  • JVM分区
  • 垃圾收集算法
  • synchronized原理
  • 双亲委派机制
  • 线程池参数
  • newFixedTheadPool底层,优缺点
  • springmvc
  • @Autowired原理
  • springboot原理
  • @OnConditionalClass实现原理
  • @OnMissingBean没有bean会怎么样,会classNotFound
  • HashMap 底层数据结构
  • HashMap 什么时候扩容?装载因子和临界值默认是多少?扩容成多大?为什么容量是2的幂次方?
  • 线程安全的Map?分段锁是如何实现的?JDK 1.8之后有哪些优化?
  • Lock和Synchronized区别
  • AQS实现
  • 锁优化
  • String StringBuilder StringBuffer区别,特点,场景
  • ConcurrentMap 源码
  • CMS
  • 线程生命周期(状态)
  • ReentrantLock与AQS同步框架
  • CAS原理是什么?
  • synchronize原理是什么?
  • springboot 和 spring 的区别是什么?
  • spring中bean的初始化过程
  • 谈一谈异常机制
  • Spring IOC和AOP
  • Arrays.sort()底层原理

场景题

  • 一个8G的服务器,堆的大小应该设置成多少
  • 海量数据求频率最多的100个
  • spring一个事务中调用另外一个事务,另一个- 事务发生异常会怎么样
  • 一个父类加载器能不能加载一个子类加载器,为什么
  • select * from A where id in (select id from B)怎么优化
  • 一个16G的内存堆分配多少,采用什么垃圾收集器,为什么用cms不用g1,为什么(面试官一直问为什么使用cms或者使用g1,回答了这两个的优缺点之后还是不满意)
  • 多线程解析一个超大文件怎么处理,如果文件切分的时候关键信息被分到了不同的解析线程中怎么办
  • hashset是如何判断两个对象相等的
  • 如何要两个对象相等equals和hashcode这两个方法要怎么重写
  • hash算法(最开始讲hash冲突算法,面试官说不是这个,我又说对hash值对质数取余,面试官也说不是这个,不知道他要我回答啥。。。)
  • 不使用任何优化,直接访问数据库,如何优化 (提示 redo、undo log的开销)(这里应该还可以答:批处理、连接池等)
  • 行锁锁的是索引,如果一个表没有主键怎么加锁?(锁表)
  • hashmap 为什么不直接用红黑树,还要用链表?
  • 红黑树的特性?各种操作的时间复杂度?最多旋转几次达到平衡?
  • finally 中 return 会发生什么?
  • 如何破坏双亲委派
  • 浏览器中用户信息和密码的安全有没有考虑过
  • 两个线程如何交替打印A和B
  • 100万个数,数据类型是int,给你8核CPU,8G内存,如何求数组的和?
  • 很多个不重复的数,假设用的数组来装,我希望你实现一个方法,每次调用这个方法给我随机返回100个不重复,记住是随机的。
  • 四个引用的具体应用场景
  • 垃圾回收器具体应用场景
  • 可达性分析算法具体应用场景
  • 垃圾回收器参数调优(给具体场景 大概就是并发低延时)
  • 高并发多连接jvm 线程池参数调优(顺着来)
  • 高并发系统调优(再顺一下)
  • 队列与栈的 应用场景
  • 点赞高并发怎么办?
  • 消息中间件用过么?怎么自己设计一个消息中间件?
  • 假设catch,final,catch中有return,那么final还会不会执行
  • 假设1亿的11位的手机号,运行空间128M,如果要进行排序,那么要怎么设计
  • jvm的设计角度,gc你怎么优化?
  • 你怎么设计md5函数?
  • cpu一直被占满,怎么排查?
  • 让你自己设计一个垃圾回收器,尽可能提高回收效率,你会怎么设计?(ZGC和香浓多,整就完事了)
  • MD5加密算法,不使用hashmap和映射,你自己来设计一个同类型的,给定字符串可以生成64位随机数的,你怎么设计
  • 利用java现有的东西,让你设计一个对象,实现类似synchronize的功能,使得多个线程不冲突,你如何设计?(ThreadLocal玩起来)
  • synchronize锁定.class和锁定一个实例有什么区别?
  • explain中的key字段的值等于ref时,有没有触发索引?
  • 如何实现单点登录,如何实现权限控制,用户密码泄露后如何保证安全性
  • spring中循环依赖如何解决?如果让你来实现你怎么做?
  • 如果我的服务器ip地址变了,客户端如何感知到呢?
  • 轮询的负载均衡的缺点是什么?如何改进?
  • 让你来实现真正的负载均衡,你如何做?(我回答记录每台服务器在最近的一段时间内接收的请求的数量,每次都把请求发送给数量最小的服务器,后来面试官提醒我还应当考虑每个请求耗费的时间)
  • 秒杀项目中静态资源CDN怎么做?
  • css文件能放到CDN上吗?
  • 秒杀缓存如何与数据库的数据保持一致性?
  • 通过广播的方式去更新每个节点的缓存,如果某个节点的缓存更新失败,那么如何排查是哪个节点呢?
  • 消费者消费失败是怎么处理的
  • 如何保证消息消费的顺序性
  • 如何保证消息不被重复消费
  • 项目中要进行分布式扩展应该怎么做
  • 缓存和mysql数据一致性如何保证
  • 微信步数排行,假设百万级用户,怎么排序,实时更新(我说排序就是海量数据排序的方式分组排序再归并,然后实时更新的话也是组内更新组内排序,但是每组的分度值可能不一样,比如0-2000可能一组,但2000-4000可能要分五组之类的,因为步数特别少和特别多的都是少数。)
  • 发生了OOM,应该怎么去分析解决?jvm调优
  • 什么时候发生线程的上下文切换?
  • CAS是硬件实现还是软件实现
  • 除了wait和notifyall,还有什么办法实现类似的功能
  • 微信抢红包设计(只讲了类似多线程抢、Semphore,缓存)、海量文件找重复次数最多的个数(分治)

MySQL

  • 索引怎么优化
  • 为什么用B+树
  • Innodb 和 Myisam 的区别
  • 聚集索引和非聚集索引 创建以后的文件大小
  • 为什么不用哈希索引?
  • 有几种事务隔离级别?
  • Innodb 行锁是如何实现的?
  • mysql怎么分页
  • 索引为什么查找快
  • 慢查询如何优化
  • mvcc原理

Redis

  • redis基本数据类型
  • redis集群?切片
  • 为什么用Redis,Redis宕机了怎么办,数据呢?怎么保持热点数据?过期机制,淘汰机制?
  • redis是单线程么?为什么快?io模型什么怎么样的,具体是怎么个流程?
  • 缓存穿透、雪崩,redis持久化机制

计网

  • tcp三次握手
  • HTTP 和RPC区别?还有呢?
  • JWT流程,安全?Session?
  • 盐有单独保存起来么
  • HTTP 和 HTTPS的区别
  • https的加密证书怎么获取
  • 加密后客户端保留的是公钥还是私钥
  • 讲一下ftp
  • cookies
  • http以及https 以及加密手段
  • 浏览器输入url后的一系列操作
  • HTTP状态码
  • 为什么用Jwt,cookie,session有什么好处?
  • TCP怎么确保可靠性的?丢包和串包怎么办?
  • DNS说一下?

操作系统

  • 上下文切换
  • 内核态用户态
  • 多路复用IO模型,select,poll,epoll

分布式

  • 怎么实现分布式锁
  • redis分布式锁有什么缺点,怎么解决
  • 单体应用和微服务区别,为什么要有微服务?好处?还有呢?
  • 微服务流程?
  • 分布式缓存?
  • 分布式session原理
  • SpringCloud及其组件你了解哪些?

算法

  • n个线程顺序循环打印0-100
  • 手写LinkedList的数据结构并写出add和remove算法
  • 微信红包算法实现
  • 链表如何找环
  • 有序链表合并
  • 共计9个苹果,有2只猴子,一个猴子每次拿2个苹果,一个猴子每次拿3个苹果,如果剩余的苹果不够猴子每次拿的数量,则2只猴子停止拿苹果,请用java多线程模拟上面的描述,要求性能尽可能高效(这个题开始是用可重入锁写的,结束之后自己本地测试发现程序不会自动结束,后来改成用AtomicInteger和cas来实现了)
  • 设计一个多线程打印程序,第i个线程只打印i-1数字,比如第1个线程打印数字0,第2个线程只打印数字1,依次类推。任意给定一个数字序列,比如3382019835830,能够使用该程序打印出来。

腾讯

算法

  • 判断树是否对称:1
  • 在一个大数组里求第100大的数字:1
  • 找出A[1000]、B[1000]、C[1000]中的重合的数字:1
  • 给出25亿个QQ号,找出其中重复的?如果不用bitmap且只有一台机器怎么做?:1
  • 你了解哪些排序?:1
  • 快排什么时候复杂度不好?:1
  • 红黑树的特点?如果给红黑树插入数据,红黑树是怎么做的?:1
  • 写一个栈:1
  • 两个特别大的数相乘:1
  • 求两个已排序数组合并后的中位数:1
  • 设计栈,使得getMin()和getMax()的时间复杂度为O(1):1
  • 一个数组中只有一个数字出现了奇数次,其他数字出现了偶数次,找到出现了奇数次的那个数:1
  • 100层楼和2个玻璃杯,怎样用最少的次数找出杯子在哪一层会碎:1
  • 哈希表是如何实现的?:1
  • 1TB的数据如何进行排序:1
  • 对100TB的数据进行排序?(拆分多个数据段进行排序,然后归并):1
  • 判断链表有环,找环入口:2
  • 100万个数找最小的10个(大顶堆):1
  • 旋转数组找出最小值:1
  • 找链表中间节点:1
  • 找链表倒数第k节点:1
  • 微信发红包 m块钱发给n个人 你怎么设计算法:1
  • 很多数中有俩数重复了咋判断:1
  • 单调栈问题:1
  • 分组反转单向链表:1
  • 非递归实现后序遍历:1
  • 把数组排成最小的数:1
  • 找第k大元素:1
  • 链表循环右移动k位置:1
  • 如何自己实现一个kv结构的,你有哪几种方式:1
  • 用hash表有什么问题,和解决了什么问题?:1
  • 用树解决了什么问题,红黑树和hash分别是有序还是无序的呢?:1
  • 为什么是有序还是无序?具体怎么实现的呢?:1

MySQl

  • mysql慢查询如何优化?:2
  • 优化器是什么时候起作用的?:1
  • MVCC的原理?:1
  • InnoDB和myISAM的区别?:2
  • InnoDB的聚集索引和MyISAM的非聚集索引的区别?:1
  • B+树、B树、红黑树的区别:2
  • 辅助索引的叶子上有什么内容?辅助索引和主键索引性能差距在哪里?:1
  • 数据库事务性质,并发一致性问题:1
  • 数据库存储过程,视图,函数的使用,几种连接方式:1
  • 索引:2
  • 事务的ACID:2
  • 数据库的join操作实际上是MySQL底层是怎么做的呢:1
  • limit a,b是什么意思,会有什么性能上的问题:1(limit之前的数据先查出来、a代表起点、b代表数量,如果a很大的话,那么MySQL需要先去遍历前a条数据而不是直接定位,所以这里存在性能问题)
  • 数据库容灾方面问题,数据库挂了怎么办:1
  • 数据库集群怎么实现数据一致性:1

java

  • 从java代码到.class文件,中间经历实现你了哪些过程?:1
  • Java数据类型,大小:1
  • instanceof和getClass:1
  • JMM:2
  • 介绍项目中的SpringIOC DI MVC AOP:1
  • JVM数据区:1
  • GC相关:1
  • OOM情况:1
  • 多态的实现:1
  • Java类的分类:1
  • 普通类,接口,抽象类的区别:1
  • Java创建线程的方式:1
  • 线程的状态:1
  • 单例模式:1
  • 类加载过程:1
  • 双亲委派模型:1
  • Java会出现内存泄露吗:1
  • 如何定位和解决OOM:1
  • Java的GC中什么场景下使用CMS和G1:1
  • hashmap:1
  • JVM参数调优:1
  • Minor GC和Full GC:1
  • 线程池:1
  • spring bean的什么周期:2
  • spring 单例的bean是否线程安全:1
  • 有状态的bean和无状态的bean区别:1
  • spring事务了解么:1
  • 如何实现HashMap取出的顺序和放入顺序一致?:1
  • HashMap的扩容的时间复杂度,如何优化?:1
  • JDK8添加了哪些特性?:1
  • java为什么说它即是解释型语言,又是编译型语言:1
  • 面向对象和面向过程的区别?:1
  • java的类和c++的类有什么区别:1
  • java语言的三大特性:1
  • 怎么拼接多个string:1
  • 讲讲异常:1
  • 深拷贝和浅拷贝:1
  • java的包装类的了解?为啥要有包装类:1
  • Java的集合:1
  • 乐观锁和悲观锁:1
  • synchronize和Lock区别:1
  • synchronized的底层是怎么实现的?:1
  • ReentrantLock的区别:1
  • ThreadLocal的原理是什么:1
  • CountdownLatch:1

redis

  • redis在你项目中怎么用的?防止重复提交是怎么做到的?:1
  • Redis五种数据类型:1
  • Hash底层:1
  • redis跳表的优势:1
  • reactor模式:1
  • redis持久化:1

计网

  • HTTP还是HTTPS请求?有什么区别?:3
  • HTTP过程的四次挥手?:2
  • TIME_WAIT的作用?:2
  • cookie的作用?:1
  • 腾讯和百度两个网页能获取对方的cookie吗?:1
  • 在百度里搜索abc的过程?:1
  • 搜索的时候,数据包是怎么交给网卡的?(7层 5层网络模型)层层封包都加的是什么内容?:1
  • 网卡怎么知道数据是发送给百度服务器的,怎么找到服务器的?:1
  • 计算机网络分层,各层的协议:1
  • http流量控制,拥塞避免如何实现:1
  • 多少种请求方式,get和post区别:1
  • Https端口443以及怎么的实现流程:1
  • Session和Cookie区别:1
  • TCP和UDP的区别:1
  • TCP三次握手:1
  • CLOSE_WAIT:1
  • DNS解析的过程:1
  • HTTP长连接和短连接:1
  • TCP拥塞控制:1
  • 了解粘包吗,怎么设置不粘包:1
  • sql注入如何防范:1
  • xss如何防范:1
  • udp的最大包长度,为什么这么大?:1
  • 傻瓜窗口了解吗?怎么解决?:1
  • socket去写的时候你会怎么写?考虑什么?:1
  • http常见头部信息有哪些:1
  • 你知道https的非对称加密和对称加密使用了哪些算法么:1

os

  • 内核态和用户态的区别?:1
  • 用户态通过什么样的接口调用内核?
  • 进程在内存中是如何分配的?(段页式及其细节、数据段、栈段、代码段):1
  • 操作系统进程同步方式:1
  • 进程怎样通信:2
  • 套接字:1
  • 线程通信机制:1
  • CPU密集型任务适合多进程还是多线程?:1
  • 进程的同步机制,你在什么时候用:1
  • 向一个进程发出kill信号接下来发生什么?:1
  • 共享内存的坏处:1
  • 操作系统中中断的分类:1
  • 操作系统页置换算法:1
  • 僵尸进程问题:1
  • 页式和段式的区别,优缺点,应用场景。:1
  • 讲一下虚拟内存、页表:1
  • 为什么顺序io比随机io快?:1
  • 随机io的过程是什么?:1
  • 用户态和内核态的区别?如何切换?:1
  • 原子操作的意义:1
  • i++为什么不是原子操作,如何去保证是原子操作?:1

分布式

  • 高并发系统大量请求如何优化:1
  • 分布式系统CAP:1
  • 秒杀系统解决超卖问题,(数据库排它锁和乐观锁CAS版本号机制):1
  • base理论:1
  • 两阶段提交:1
  • redis分布式锁的注意事项,实现过程?:1

亮点

  • Netty,NIO通信框架:1
  • BIO、NIO、AIO:1
  • NIO又可以分为三种,基于轮询、基于多路复用、基于事件回调:1
  • 如何指定使用哪种方式:1
  • 知道他底层怎么实现的吗:1
  • Netty底层Buffer的实现:1
  • 日志清理如何解决:1
  • 日志合并如何解决:1
  • reactor模式:1
  • 讲讲netty的io模型:1
  • 讲讲多路复用机制,你觉得什么时候多路复用性能会比较好?

字节

算法(好多树)

  • 每K个节点翻转链表(链表k个一旋转):2
  • 二叉搜索树转链表:1
  • 负载均衡算法:1
  • 排序算法哪些是稳定的:1
  • 二叉树求和:1
  • 序列化和反序列化二叉树:1
  • 如何判断一颗树是否是完全二叉树:1
  • 求数组的极值点:1
  • 最大连续子序列:1
  • 回文链表:1
  • 链表反转:1
  • 对称二叉树:1
  • 二叉树右视图:1
  • 移动零:1
  • 给定链表,确定中间数:1
  • 链表奇数位升序、偶数位降序:1
  • 二叉树的左视图:1
  • 一致性hash:1
  • 旋转数组的最小值:1
  • 判断两个链表是否交叉?:1
  • 三数之和:1
  • 两个链表相加:1
  • 给一个序列判断是不是二叉搜索树的后序遍历:1
  • 单词翻转
  • 二叉树层序遍历:1
  • 最长连续子串:1
  • 岛屿:1
  • 无重复字符的最长字串:1
  • 设计一个数据结构 list: rpush rpop lpush lpop index 五种方法的时间复杂度均为 O(1),数据量上限是100w(我回答使用双端队列+hashMap, 面试官说可以用两个数组实现)
  • 求集合的子集:1
  • 字符串全排列:1

Java(所有谈谈的,老哥我最喜欢了,狂吹)

  • 常见的GC回收器,越详细越好:1
  • SpringMVC的请求过程:1
  • 常见的GC回收器,越详细越好:1
  • 线程池(所有你知道的),原理尽量详细些:2
  • HashMap底层实现:1
  • concurrenthashmap:1
  • ConcurrentHashMap的扩容机制:1
  • LinkedHashMap 底层数据结构?使用场景? :1
  • Spring AOP怎么实现,围绕bean生命周期去讲:1
  • 三大特性:1
  • 谈谈多态:2
  • 接口和抽象类的区别:1
  • 谈谈集合:1
  • Arraylist和LinkedList的区别:1
  • Hashmap底层:1
  • ==跟equals的区别:1
  • 有界无界队列:1
  • 线程的创建方法:1
  • 深拷贝、浅拷贝:1
  • sychronized:1
  • GC算法:1
  • JVM内存结构:1
  • 谈谈cas:1
  • 谈谈JVM:1
  • JDK动态代理:1
  • 类加载的过程:1
  • 说说Object类,作用,有什么方法:1
  • Treeset Treemap的底层实现:1
  • volatile:1
  • 谈谈反射:1

字节问的Java没啥难度,简单的一批

计算机网络

  • https通信过程:1
  • https加密过程,怎么判断证书的有效性:1
  • tcp、udp区别
  • tcp(所有):1
  • TCP拥塞控制:1
  • TCP滑动窗口:1
  • http 头部有哪些key:1
  • http状态码有哪些:1
  • DNS服务器怎么处理域名请求的,了解原理吗:1
  • GET、POST:1
  • HTTP2.0有哪些改动:1
  • 路由器怎么工作的:1
  • 七层协议讲一下:1
  • http是否无状态?如何有状态?session和Cookies的区别:1

MySQL

  • 聚簇索引和非聚簇索引底层实现:1
  • 隔离级别:2
  • mysql在业务中怎么实现乐观锁:1(MVCC各种吹)
  • MVCC原理,和for update有什么区别:1
  • Innodb\myisam区别:1
  • 谈谈B+树前世今生以及所有:1
  • ACID:1
  • 联合索引底层结构:1
  • SQL里where having分别是做什么的,有什么区别,什么时候用:1
  • MySQL索引类别:1
  • 左连接和内连接的区别:1
  • 谈谈binlog和redolog :1

题:

  • 获取所有课程得分均大于80分的学生的平均得分:2

Redis

  • 分布式锁怎么实现,Redis加锁过程:1
  • Redis的setnx有哪些注意点,比如宕机时会发生什么:1
  • zset底层原理:(吹它的跳跃表和压缩列表):3
  • Redis中的哨兵:1
  • 谈谈Redis集群 Redis Cluster,以及主从复制原理:1
  • redis的hashmap和java的hashmap有何异同:1
  • 持久化策略:1
  • 利用redis的可重入锁如何设计:1
  • redis分布式锁是否公平锁?

操作系统

  • 进程间通信有哪些,各个优缺点:2
  • select/poll/epoll:2
  • 用户态、内核态:1
  • 信号量 同步 互斥的区别:1
  • 页面的置换算法:1
  • 进程间的同步方式用过哪些:1

linux

  • linux如何查找CPU故障

RocketMQ

  • RocketMQ有哪些组件:1

Mybatis

  • mybatis的缓存:1

项目

  • Jmeter压测的时候为什么会丢包

感觉字节基本没有Spring,可惜了,问的Java也比较基础!! 如果有中间件的话,多熟悉熟悉。 其次就是计算机网络和操作系统的知识多熟悉熟悉,最后就是大家都知道的算法!!!

以上还有各个大厂总结的面经,都在链接:https://github.com/DreamCats/Dc-Notes

#面经##Java##校招##字节跳动##阿里巴巴##腾讯#
全部评论
76.CAS是硬件实现还是软件实现:比较当前工作内存中的值和主内存中的值,如果相同则执行规定操作,否则继续比较直到主内存和工作内存中的值一致为止。它是一条CPU并发原语;它的功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,这个过程是原子的。 CAS并发原语体现在java语言中就是sun.misc.Unsafe类中的各个方法。调用UnSafe类中的CAS方法,JVM会帮我们实现出CAS汇编指令。这是一种完全依赖于硬件的功能,通过它实现了原子操作。再此强调,由于CAS是一种系统原语,原语属于操作系统用语范畴,是由若干条指令组成的,用于完成某个功能的一个过程,并且原语的执行是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致问题。 CAS应用 CAS有3个操作数,内存值V,旧的预期值A,要修改的更新值B。 当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
点赞 回复 分享
发布于 2022-06-10 22:20
75.什么时候发生线程的上下文切换: 1、自发性上下文切换-主要由Java程序导致,让程序中执行一下操作的时候会导致线程自发上下文切换 sleep()、wait()、yield()、join()、park()、synchronized、lock等。 2、非自发性上下文切换一般由于线程时间片用完、虚拟机垃圾回收(STW)导致线程暂停、线程优先级导致等。 3、线程上下文切换的检测方式: vmstat 查看Java程序系统上下文切换频率, pidstat 监控指定进程上下文切换。 4、线程越多,速度不一定越快,一般简单逻辑,执行速度快使用单线程。逻辑相对复杂并且等待时间长、需要大量计算的时候,例如NIO文件读写、图像处理、大数据分析等推荐使用多线程处理。 5、多线程中使用Synchronized 会发生线程上下文切换和进程上下文切换
点赞 回复 分享
发布于 2022-06-10 22:16
74. 7、 Kill process&nbs***bsp;sacrifice child 有一种内核作业(Kernel Job)名为 Out of Memory Killer,它会在可用内存极低的情况下“杀死”(kill)某些进程。OOM Killer 会对所有进程进行打分,然后将评分较低的进程“杀死”,具体的评分规则可以参考 Surviving the Linux OOM Killer。 不同于其他的 OOM 错误, Killprocessorsacrifice child 错误不是由 JVM 层面触发的,而是由操作系统层面触发的。 原因分析 默认情况下,Linux 内核允许进程申请的内存总量大于系统可用内存,通过这种“错峰复用”的方式可以更有效的利用系统资源。 然而,这种方式也会无可避免地带来一定的“超卖”风险。例如某些进程持续占用系统内存,然后导致其他进程没有可用内存。此时,系统将自动激活 OOM Killer,寻找评分低的进程,并将其“杀死”,释放内存资源。 解决方案 1、升级服务器配置/隔离部署,避免争用。 2、OOM Killer 调优。 8、Requested array size exceeds VM limit JVM 限制了数组的最大长度,该错误表示程序请求创建的数组超过最大长度限制。 JVM 在为数组分配内存前,会检查要分配的数据结构在系统中是否可寻址,通常为 Integer.MAX_VALUE-2。 此类问题比较罕见,通常需要检查代码,确认业务是否需要创建如此大的数组,是否可以拆分为多个块,分批执行。 9、Direct buffer memory Java 允许应用程序通过 Direct ByteBuffer 直接访问堆外内存,许多高性能程序通过 Direct ByteBuffer 结合内存映射文件(Memory Mapped File)实现高速 IO。 原因分析 Direct ByteBuffer 的默认大小为 64 MB,一旦使用超出限制,就会抛出 Directbuffer memory 错误。
点赞 回复 分享
发布于 2022-06-10 22:13
74. 1、JVM 内部的应用程序请求创建一个新的 Java 线程; 2、JVM native 方法代理了该次请求,并向操作系统请求创建一个 native 线程; 3、操作系统尝试创建一个新的 native 线程,并为其分配内存; 4、如果操作系统的虚拟内存已耗尽,或是受到 32 位进程的地址空间限制,操作系统就会拒绝本次 native 内存分配; 5、JVM 将抛出 java.lang.OutOfMemoryError:Unableto createnewnativethread 错误。 解决方案 1、升级配置,为机器提供更多的内存; 2、降低 Java Heap Space 大小; 3、修复应用程序的线程泄漏问题; 4、限制线程池大小; 5、使用 -Xss 参数减少线程栈的大小; 6、调高 OS 层面的线程最大数:执行 ulimia-a 查看最大线程数限制,使用 ulimit-u xxx 调整最大线程数限制。 ulimit -a .... 省略部分内容 ..... max user processes (-u) 16384 6、Out of swap space? 该错误表示所有可用的虚拟内存已被耗尽。虚拟内存(Virtual Memory)由物理内存(Physical Memory)和交换空间(Swap Space)两部分组成。当运行时程序请求的虚拟内存溢出时就会报 Outof swap space? 错误。 原因分析 该错误出现的常见原因包括以下几类: 1、地址空间不足; 2、物理内存已耗光; 3、应用程序的本地内存泄漏(native leak),例如不断申请本地内存,却不释放。 4、执行 jmap-histo:live<pid> 命令,强制执行 Full GC;如果几次执行后内存明显下降,则基本确认为 Direct ByteBuffer 问题。 解决方案 根据错误原因可以采取如下解决方案: 1、升级地址空间为 64 bit; 2、使用 Arthas 检查是否为 Inflater/Deflater 解压缩问题,如果是,则显式调用 end 方法。 3、Direct ByteBuffer 问题可以通过启动参数 -XX:MaxDirectMemorySize 调低阈值。 4、升级服务器配置/隔离部署,避免争用。
点赞 回复 分享
发布于 2022-06-10 22:12
74. 4、JIT 编译器优化后的 class 信息。 PermGen 的使用量与加载到内存的 class 的数量/大小正相关。 解决方案 根据 Permgen space 报错的时机,可以采用不同的解决方案,如下所示: 1、程序启动报错,修改 -XX:MaxPermSize 启动参数,调大永久代空间。 2、应用重新部署时报错,很可能是没有应用没有重启,导致加载了多份 class 信息,只需重启 JVM 即可解决。 3、运行时报错,应用程序可能会动态创建大量 class,而这些 class 的生命周期很短暂,但是 JVM 默认不会卸载 class,可以设置 -XX:+CMSClassUnloadingEnabled 和 -XX:+UseConcMarkSweepGC 这两个参数允许 JVM 卸载 class。 如果上述方法无法解决,可以通过 jmap 命令 dump 内存对象 jmap-dump:format=b,file=dump.hprof<process-id> ,然后利用 Eclipse MAT 功能逐一分析开销最大的 classloader 和重复 class。 4、Metaspace JDK 1.8 使用 Metaspace 替换了永久代(Permanent Generation),该错误表示 Metaspace 已被用满,通常是因为加载的 class 数目太多或体积太大。 此类问题的原因与解决方法跟 Permgenspace 非常类似,可以参考上文。需要特别注意的是调整 Metaspace 空间大小的启动参数为 -XX:MaxMetaspaceSize。 5、Unable to create new native thread 每个 Java 线程都需要占用一定的内存空间,当 JVM 向底层操作系统请求创建一个新的 native 线程时,如果没有足够的资源分配就会报此类错误。 原因分析 JVM 向 OS 请求创建 native 线程失败,就会抛出 Unableto createnewnativethread,常见的原因包括以下几类: 1、线程数超过操作系统最大线程数 ulimit 限制; 2、线程数超过 kernel.pid_max(只能重启); 3、native 内存不足; 该问题发生的常见过程主要包括以下几步:
点赞 回复 分享
发布于 2022-06-10 22:11
74.发生了OOM,应该怎么去分析解决: 1、Java heap space 当堆内存(Heap Space)没有足够空间存放新创建的对象时,就会抛出 java.lang.OutOfMemoryError:Javaheap space 错误(根据实际生产经验,可以对程序日志中的 OutOfMemoryError 配置关键字告警,一经发现,立即处理)。 原因分析 Javaheap space 错误产生的常见原因可以分为以下几类: 1、请求创建一个超大对象,通常是一个大数组。 2、超出预期的访问量/数据量,通常是上游系统请求流量飙升,常见于各类促销/秒杀活动,可以结合业务流量指标排查是否有尖状峰值。 3、过度使用终结器(Finalizer),该对象没有立即被 GC。 4、内存泄漏(Memory Leak),大量对象引用没有释放,JVM 无法对其自动回收,常见于使用了 File 等资源没有回收。 解决方案 针对大部分情况,通常只需要通过 -Xmx 参数调高 JVM 堆内存空间即可。如果仍然没有解决,可以参考以下情况做进一步处理: 1、如果是超大对象,可以检查其合理性,比如是否一次性查询了数据库全部结果,而没有做结果数限制。 2、如果是业务峰值压力,可以考虑添加机器资源,或者做限流降级。 3、如果是内存泄漏,需要找到持有的对象,修改代码设计,比如关闭没有释放的连接。 2、GC overhead limit exceeded 当 Java 进程花费 98% 以上的时间执行 GC,但只恢复了不到 2% 的内存,且该动作连续重复了 5 次,就会抛出 java.lang.OutOfMemoryError:GC overhead limit exceeded 错误。简单地说,就是应用程序已经基本耗尽了所有可用内存, GC 也无法回收。 此类问题的原因与解决方案跟 Javaheap space 非常类似,可以参考上文。 3、Permgen space 该错误表示永久代(Permanent Generation)已用满,通常是因为加载的 class 数目太多或体积太大。 原因分析 永久代存储对象主要包括以下几类: 1、加载/缓存到内存中的 class 定义,包括类的名称,字段,方法和字节码; 2、常量池; 3、对象数组/类型数组所关联的 class;
点赞 回复 分享
发布于 2022-06-10 22:09
73.秒杀缓存如何与数据库的数据保持一致性: 先更新数据库,后删除缓存(推荐) 1可能出现的问题 更新数据库成功了,但是在删除缓存的阶段没有成功,则之后读取的缓存都是错误的 2解决方式一:异步实现之利用消息队列  请求A向服务端发送修改商品请求  相应的模块根据请求会对数据库对应内容进行更新,更新成功后会向MQ发送消息 该消息通知缓存处理模块删除对应的缓存  缓存模块监听到有新的消息,会执行缓存删除逻辑  利用消息队列的手动提交机制可以保证删除逻辑顺利完成 3 解决方式二:基于Canal的通知 商品服务完成数据库修改操作后,业务直接结束。没有任何代码侵入 Canal监听mysql变化,当发现变化后,立即通知缓存服务 缓存服务接收到canal通知,删除缓存。
点赞 回复 分享
发布于 2022-06-10 22:01
72.轮询的负载均衡的缺点是什么: Nginx的优点是:  1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是它目前广泛流行的主要原因之一,Nginx单凭这点可利用的场合就远多于LVS了。 2、Nginx对网络稳定性的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势之一;相反LVS对网络稳定性依赖比较大,这点本人深有体会; 3、Nginx安装和配置比较简单,测试起来比较方便,它基本能把错误用日志打印出来。LVS的配置、测试就要花比较长的时间了,LVS对网络依赖比较大。 3、可以承担高负载压力且稳定,在硬件不差的情况下一般能支撑几万次的并发量,负载度比LVS相对小些。 4、Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx会把上传切到另一台服务器重新处理,而LVS就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而不满。 5、Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP也是近几年非常流行的web架构,在高流量的环境中稳定性也很好。 6、Nginx现在作为Web反向加速缓存越来越成熟了,速度比传统的Squid服务器更快,可以考虑用其作为反向代理***。 7、Nginx可作为中层反向代理使用,这一层面Nginx基本上无对手,唯一可以对比Nginx的就只有lighttpd了,不过lighttpd目前还没有做到Nginx完全的功能,配置也不那么清晰易读,社区资料也远远没Nginx活跃。 8、Nginx也可作为静态网页和图片服务器,这方面的性能也无对手。还有Nginx社区非常活跃,第三方模块也很多。 Nginx的缺点是: 1、Nginx仅能支持http、https和Email协议,这样就在适用范围上面小些,这个是它的缺点。 2、对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测。不支持Session的直接保持,但能通过ip_hash来解决。
点赞 回复 分享
发布于 2022-06-10 21:55
71.Spring如何解决循环依赖:依赖循环就是多个bean之间相互依赖,形成了一个闭环。 比如:A依赖于B、B依赖于c、c依赖于A。1,Spring中单例Bean的三级缓存:第一级缓存〈也叫单例池)singletonObjects:存放已经经历了完整生命周期的Bean对象 第二级缓存: earlySingletonObjects,存放早期暴露出来的Bean对象,Bean的生命周期未结束(属性还未填充完整) 第三级缓存: Map<String, ObiectFactory<?>> singletonFactories,存放可以生成Bean的工厂。 2,Spring中Bean的生命周期。3,Bean初始化主要方法:getSingleton:希望从容器里面获得单例的bean,doCreateBean: 没有就创建bean,populateBean: 创建完了以后,要填充属性, addSingleton: 填充完了以后,再添加到容器进行使用 4,具体说明 A创建过程中需要B,于是A将自己放到三级缓存里面,去实例化B B实例化的时候发现需要A,于是B先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了A然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A B顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)然后回来接着创建A,此时B已经创建结束,直接从一级缓存里面拿到B,然后完成创建,并将A放到一级缓存中。
点赞 回复 分享
发布于 2022-06-10 21:22
70.如何实现单点登录,如何实现权限控制,用户密码泄露后如何保证安全性:单点登录的英文名叫做:Single Sign On(简称SSO),指在同一帐号平台下的多个应用系统中,用户只需登录一次,即可访问所有相互信任的系统。简而言之,多个系统,统一登陆。单点登录原理 sso需要一个独立的认证中心,所有子系统都通过认证中心的登录入口进行登录,登录时带上自己的地址,子系统只接受认证中心的授权,授权通过令牌(token)实现,sso认证中心验证用户的用户名密码正确,创建全局会话和token,token作为参数发送给各个子系统,子系统拿到token,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。 单点登录的实现方案,一般就包含:Cookies,Session同步,分布式Session,目前的大型网站都是采用分布式Session的方式。 1.基于Cookie+Redis的单点登录 最简单的单点登录实现方式,用cookie作为媒介存放用户凭证。 用户登录系统之后,会返回一个加密的cookie,当用户访问子应用的时候会带上这个cookie,授权以解密cookie并进行校验,校验通过后即可登录当前用户。 2.分布式session方式实现单点登录  流程运行: (1) 用户第一次登录时,将会话信息(用户Id和用户信息),比如以用户Id为Key,写入分布式Session; (2) 用户再次登录时,获取分布式Session,是否有会话信息,如果没有则调到登录页; (3)建议使用Redis,因此它有持久化功能,方便分布式Session宕机后,可以从持久化存储中加载会话信息; (4) 存入会话时,可以设置会话保持的时间,比如15分钟,超过后自动超时; 结合Cache中间件,实现的分布式Session,可以很好的模拟Session会话。 3.使用token实现 1.在项目某个模块进行登录,登录之后,按照规则生成字符串,把登陆之后用户包含到生成字符串里面,把字符串返回(1)可以把字符串通过cookie返回(2)把字符串通过地址栏返回 2.再去访问项目其他模块,每次访问在地址栏带着生成的字符串,在访问模块里面获取地址字符串,根据字符串获取用户信息。如果可以获取到就能登录。
点赞 回复 分享
发布于 2022-06-10 21:13
69.MD5加密算法: MD5特点: 1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。 2、容易计算:从原数据计算出MD5值很容易。 3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。 4、弱抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。 5、强抗碰撞:想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的。 //使用MD5的算法进行加密代码:     public static String md5(String plainText) {              byte[] secretBytes = null;              try {                     secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());                    } catch (NoSuchAlgorithmException e) {                          throw new RuntimeException("没有MD5这个算法!");                    }               // 16进制数字                       String md5code = new BigInteger(1, secretBytes).toString(16);               // 如果生成数字未满32位,需要前面补0                       while(md5code.length() < 32){                      md5code = "0" + md5code;               }                      return md5code;     }
点赞 回复 分享
发布于 2022-06-10 19:14
68.cpu一直被占满,怎么排查:1.定位进程 登录服务器,执行top命令,查看CPU占用情况: $top 2.定位线程 如果进程23456占用率高: $top -Hp23456 进行定位线程 3.定位代码 通过top命令,我们目前已经定位到导致CPU使用率较高的具体线程,比如线程4519, 那么我么接下来就定位下到底是哪一行代码存在问题。 首先,我们需要把具体的线程转成16进制: $printf %x4519 11a7 接下来,通过jstack命令,查看栈信息: $sudo -u admin jstack23456|grep -A20011a7 通过以上命令,我么可以看到是代码中哪行出现了问题,重构代码即可。
点赞 回复 分享
发布于 2022-06-10 18:45
67.假设1亿的11位的手机号,运行空间128M,如果要进行排序,那么要怎么设计: 本问题中,可以借鉴归并排序的思路,将大文件拆成100个小文件,小文件内部排好序,然后进行100路的归并操作。 步骤 将 1. G的大文件,经过一遍按行读写的方式(迭代器模式)进行处理,拆成 100 100 100个小文件,每个小文件中存放100万个手机号。 分别将100个小文件读进内存,将手机号从小到大排序,排序结果写回对应的小文件中。 通过一个小顶堆形式的优先级队列(PriorityQueue)进行归并操作。堆中的元素是一个二元组:(手机号, 该手机号对应的小文件编号)。 一开始,将每个文件的第一个手机号读出来放到小顶堆中。由于这 100 100 100个手机号分别是各个子文件中最小的,因此,此时小顶堆堆顶的手机号就是全局最小的手机号。因此可以将堆顶元素弹出,写到最终的输出文件mobiles_sorted.txt中。 每次从堆顶弹出一个元素后,如果该元素所对应的小文件还没被处理完,就从相应小文件中读入下一个手机号,补充到堆中。 所有手机号都各自加入和弹出小顶堆一次后,排序完成,此时的mobiles_sorted.txt文件就是最终结果
点赞 回复 分享
发布于 2022-06-10 18:36
66.消息中间件就是一个队列,放进去取出来 业务和业务之间的联系,不做任何的逻辑 web中间件 nginx中间件 还有数据库中间件,访问数据库变得高效 应用场景 异步解耦 场景1 订单服务-调用积分服务,当积分服务挂了,积分服务不可用,当订单服务继续调用就会报错. 使用消息中间件,将订单信息传递到订单中心,订单中心会给积分服务进行调用积分服务 即使宕机数据也不会丢失,数据有做持久化 2.削峰填谷 当某个时段有大量数据进来可能会导致宕机,可以用消息中间件限流(排队慢慢进来,防止挤爆数据库) 3.数据分发 服务A调用BCD,当B下线,E上线需该代码 常见的消息中间件: ActiveMQ是Apache出品,比较老的一个开源的消息中间件,以前在中小企业应用广泛. Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 RabbitMQ 是一个基于Erlang 语言开发的消息中间件, RabbitMQ 最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。对数据的一致性,稳定性和可靠性要求比较高的场景 RocketMQ 是阿里巴巴在 2012 年开源的分布式消息中间件,目前已经捐赠给 Apache 软件基金会,并于 2017 年 9 月 25 日成为 Apache 的顶级项目。目前 RocketMQ 在阿里集团被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理, binlog 分发等场景。
点赞 回复 分享
发布于 2022-06-10 18:27
64.队列与栈的 应用场景: 栈(后进先出)可以用于字符匹配,数据反转等场景。 队列(先进先出)可以用于任务队列,共享打印机的场景。 65.点赞高并发: 一、微博点赞业务场景分析 梳理点赞的业务场景,它由两个接口: 第一个:点赞或取消点赞,用户点击功能 第二个:查看帖子信息:通过用户id 和帖子id查看改帖子,查看该帖子点赞数,查看该用户是否点赞状态。 二、微博点赞的技术方案 点赞的关键技术就是要判断该用户是否点赞,已点赞的用户不允许重复点赞,即过滤重复,虽然业务不复杂,可以采用数据库 直接实现,但是对应微博这种高并发的场景,不可能查数据的,一般是缓存,即redis 第一个:点赞或取消点赞,用户点击功能 采用的是redis的set数据接口,key=like:postid value={userid} 采用sadd命令添加点赞,采用srem命令,取消点赞 第二个:查看帖子信息:通过用户id 和帖子id查看改帖子,查看该帖子点赞数,查看该用户是否点赞状态。 采用scard命令,查看点赞总数 该用户是否点赞,采用sismember 判断某一个元素是否在set中
点赞 回复 分享
发布于 2022-06-10 18:08
63.垃圾回收器参数调优: CMS相关参数: PromotionFailed 垃圾回收时promotionfailed是个很头痛的问题,一般可能是两种原因产生,第一个原因是救助空间不够,救助空间里的对象还不应该被移动到年老代,但年轻代又有很多对象需要放入救助空间;第二个原因是年老代没有足够的空间接纳来自年轻代的对象;这两种情况都会转向Full GC,网站停顿时间较长。 解决方案一: 第一个原因最终解决办法是去掉救助空间,设置-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0即可,第二个原因解决办法是设置CMSInitiatingOccupancyFraction为某个值(假设70),这样年老代空间到70%时就开始执行CMS,年老代有足够的空间接纳来自年轻代的对象。 解决方案一的改进方案: 又有改进了,上面方法不太好,因为没有用到救助空间,所以年老代容易满,CMS执行会比较频繁。改善了一下,还是用救助空间,但是把救助空间加大,这样也不会有promotion failed。具体操作上,32位Linux和64位Linux好像不一样,64位系统似乎只要配置MaxTenuringThreshold参数,CMS还是有暂停。为了解决暂停问题和promotion failed问题,最后设置-XX:SurvivorRatio=1 ,并把MaxTenuringThreshold去掉,这样即没有暂停又不会有promotoin failed,而且更重要的是,年老代和永久代上升非常慢(因为好多对象到不了年老代就被回收了),所以CMS执行频率非常低,好几个小时才执行一次,这样,服务器都不用重启了。 G1调优建议: 不要手动设置新生代和老年代的大小,只设置这个堆的大小 不断调优暂停时间目标-XX:MaxGCPauseMillis 适当增加堆内存大小 G1 GC是启发式算***动态调整年轻代的空间大小。目标也就是为了达到接近预期的暂停时间。G1提供了两种GC模式,Young GC和Mixed GC,两种都是Stop The World(STW)的。Mixed GC的触发也是由一些参数控制。比如XX:InitiatingHeapOccupancyPercent表示老年代占整个堆大小的百分比,默认值是45%,达到该阈值就会触发一次Mixed GC
点赞 回复 分享
发布于 2022-06-10 17:59
62.JVM调优参数参考 1.针对JVM堆的设置,一般可以通过-Xms -Xmx限定其最小、最大值,为了防止垃圾收集器在最小、最大之间收缩堆而产生额外的时间,通常把最大、最小设置为相同的值; 2.年轻代和年老代将根据默认的比例(1:2)分配堆内存, 可以通过调整二者之间的比率NewRadio来调整二者之间的大小,也可以针对回收代。 比如年轻代,通过 -XX:newSize -XX:MaxNewSize来设置其绝对大小。同样,为了防止年轻代的堆收缩,我们通常会把-XX:newSize -XX:MaxNewSize设置为同样大小。 3.年轻代和年老代设置多大才算合理 1)更大的年轻代必然导致更小的年老代,大的年轻代会延长普通GC的周期,但会增加每次GC的时间;小的年老代会导致更频繁的Full GC 2)更小的年轻代必然导致更大年老代,小的年轻代会导致普通GC很频繁,但每次的GC时间会更短;大的年老代会减少Full GC的频率 如何选择应该依赖应用程序对象生命周期的分布情况: 如果应用存在大量的临时对象,应该选择更大的年轻代;如果存在相对较多的持久对象,年老代应该适当增大。但很多应用都没有这样明显的特性。 在抉择时应该根 据以下两点: (1)本着Full GC尽量少的原则,让年老代尽量缓存常用对象,JVM的默认比例1:2也是这个道理 。 (2)通过观察应用一段时间,看其他在峰值时年老代会占多少内存,在不影响Full GC的前提下,根据实际情况加大年轻代,比如可以把比例控制在1:1。但应该给年老代至少预留1/3的增长空间。 4.在配置较好的机器上(比如多核、大内存),可以为年老代选择并行收集算法: -XX:+UseParallelOldGC ,默认为Serial收集。 5.线程堆栈的设置:每个线程默认会开启1M的堆栈,用于存放栈帧、调用参数、局部变量等,对大多数应用而言这个默认值太了,一般256K就足用。 理论上,在内存不变的情况下,减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统。
点赞 回复 分享
发布于 2022-06-10 17:15
62.高并发多连接jvm 线程池参数调优: 1.监控GC的状态 使用各种JVM工具,查看当前日志,分析当前JVM参数设置,并且分析当前堆内存快照和gc日志,根据实际的各区域内存划分和GC执行时间,觉得是否进行优化。 举一个例子: 系统崩溃前的一些现象: 每次垃圾回收的时间越来越长,由之前的10ms延长到50ms左右,FullGC的时间也有之前的0.5s延长到4、5s,FullGC的次数越来越多,最频繁时隔不到1分钟就进行一次FullGC年老代的内存越来越大并且每次FullGC后年老代没有内存被释放之后系统会无法响应新的请求,逐渐到达OutOfMemoryError的临界值,这个时候就需要分析JVM内存快照dump。 2.生成堆的dump文件 通过JMX的MBean生成当前的Heap信息,大小为一个3G(整个堆的大小)的hprof文件,如果没有启动JMX可以通过Java的jmap命令来生成该文件。 3.分析dump文件 打开这个3G的堆信息文件,显然一般的Window系统没有这么大的内存,必须借助高配置的Linux,几种工具打开该文件: Visual VM IBM HeapAnalyzer JDK 自带的Hprof工具 Mat(Eclipse专门的静态内存分析工具)推荐使用 备注:文件太大,建议使用Eclipse专门的静态内存分析工具Mat打开分析。 4.分析结果,判断是否需要优化 如果各项参数设置合理,系统没有超时日志出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化,如果GC时间超过1-3秒,或者频繁GC,则必须优化。 注:如果满足下面的指标,则一般不需要进行GC: Minor GC执行时间不到50ms; Minor GC执行不频繁,约10秒一次; Full GC执行时间不到1s; Full GC执行频率不算频繁,不低于10分钟1次; 5.调整GC类型和内存分配 如果内存分配过大或过小,或者采用的GC收集器比较慢,则应该优先调整这些参数,并且先找1台或几台机器进行beta,然后比较优化过的机器和没有优化的机器的性能对比,并有针对性的做出最后选择。 6.不断的分析和调整 通过不断的试验和试错,分析并找到最合适的参数,如果找到了最合适的参数,则将这些参数应用到所有服务器。
点赞 回复 分享
发布于 2022-06-10 17:15
61.可达性分析算法具体应用场景: 算法思想:两个对象之间互相循环引用不好解决,那就给他们同一个父祖先,这个对象不管在哪里,只要这个对象到达GC Roots有路,也就是有引用链,那么这个对象就是可达的。反之,如果这个对象到达GC Roots没路了,不可达,那么这个对象已死不可用。图中 Object5,6,7就因为不可达,所有可以被回收。 那么问题来了,这个GC Roots又是何方神圣? 其实这个就是对象,在Java语言中,可作为GC Roots的对象包括下面几种: 虚拟机栈(栈帧中的本地变量表)中引用的对象 方法区中类静态属性引用的对象 方法区中常量引用的对象 本地方法栈中JNI(即一般说的Native方法)引用的对象 System Class(系统类,例如Java.util.*), Thread Block(一个对象存活在一个阻塞的线程中) , Thread(线程),正在运行的线程 Busy Monitor (调用了wait()或notify()或已同步的所有内容。例如,通过调用synchronized(Object)或进入 synchronized 同步方法。静态方法表示类,非静态方法表示对象。 被这些对象引用的对象,都是可达的。
点赞 回复 分享
发布于 2022-06-10 17:11
60. 5.Parallel Old垃圾回收器(多线程标记整理算法) 简单概括下该垃圾回收器的特点:多线程,基于标记整理算法,优先考虑系统的吞吐量。 该垃圾回收器是Paralle Scavenge的老年代版本,多线程、标记整理。 在JDK1.6 之前,新生代使用ParallelScavenge 收集器只能搭配年老代的Serial Old 收集器,只能保证新生代的吞吐量优先,无法保证整体的吞吐量,Parallel Old 正是为了在年老代同样提供吞 吐量优先的垃圾收集器,如果系统对吞吐量要求比较高,可以优先考虑新生代Parallel Scavenge 和年老代Parallel Old 收集器的搭配策略。 6.CMS垃圾回收器(多线程标记清楚算法) 简单概括下该垃圾回收器的特点:多线程,基于标记清除算法,为老年代设计,追求最短停顿时间。主要有四个步骤:初始标记、并发标记、重新标记、并发清除。不会暂停用户工作线程。 全称为Concurrent mark sweep,该回收器是专门为老年代设计的,主要追求的是最短的停顿时间,采用的标记清楚算法。 7.G1垃圾回收器 简要概括下该垃圾回收器的主要特点:将堆内存分为几个大小固定的独立区域,在后台维护了一个优先列表,根据允许的收集时间回收垃圾收集价值最大的区域。相比CMS不会产生内存碎片,并且可精确控制停顿时间。分为四个阶段:初始标记、并发标记、最终标记、筛选回收 该垃圾回收器看似和CMS工作流程差不多。采用的却是标记清楚算法,但是本质上还是存在差别,尤其是讲堆内存分为大小固定的几个区域,并且维持了一个优先列表,选取其中最有价值的回收垃圾。 Garbage first 垃圾收集器是目前垃圾收集器理论发展的最前沿成果,相比与CMS 收集器,G1 收集器两个最突出的改进是: 基于标记-整理算法,不产生内存碎片。 可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收。 G1 收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域,并且跟踪这些区域 的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间,优先回收垃圾 最多的区域。区域划分和优先级区域回收机制,确保G1 收集器可以在有限时间获得最高的垃圾收 集效率。
点赞 回复 分享
发布于 2022-06-10 17:00

相关推荐

03-10 14:19
已编辑
重庆邮电大学 前端工程师
球Offer上岸👑:测试也难求一面 逆天
点赞 评论 收藏
分享
评论
9
65
分享

创作者周榜

更多
牛客网
牛客企业服务