读Java性能权威指南(第2版)笔记11_堆内存上
1.Java性能权威指南(第2版)读后总结与感想2.读Java性能权威指南(第2版)笔记01_导言3.读Java性能权威指南(第2版)笔记02_ Java SE API技巧上4.读Java性能权威指南(第2版)笔记03_ Java SE API技巧中5.读Java性能权威指南(第2版)笔记04_ Java SE API技巧下6.读Java性能权威指南(第2版)笔记05_数据库性能JDBC7.读Java性能权威指南(第2版)笔记06_数据库性能JPA&SpringData8.读Java性能权威指南(第2版)笔记07_即时编译器上9.读Java性能权威指南(第2版)笔记08_即时编译器中10.读Java性能权威指南(第2版)笔记09_即时编译器下11.读Java性能权威指南(第2版)笔记10_原生内存
12.读Java性能权威指南(第2版)笔记11_堆内存上
13.读Java性能权威指南(第2版)笔记12_堆内存中14.读Java性能权威指南(第2版)笔记13_堆内存下15.读Java性能权威指南(第2版)笔记14_垃圾回收A16.读Java性能权威指南(第2版)笔记15_垃圾回收B17.读Java性能权威指南(第2版)笔记16_垃圾回收C18.读Java性能权威指南(第2版)笔记17_垃圾回收D19.读Java性能权威指南(第2版)笔记18_垃圾回收E20.读Java性能权威指南(第2版)笔记19_垃圾回收F21.读Java性能权威指南(第2版)笔记20_垃圾回收G22.读Java性能权威指南(第2版)笔记21_垃圾回收H23.读Java性能权威指南(第2版)笔记22_ 操作系统工具和Java监控工具24.读Java性能权威指南(第2版)笔记23_ 性能分析工具25.读Java性能权威指南(第2版)笔记24_ Java飞行记录器JFR26.读Java性能权威指南(第2版)笔记25_性能测试方法上27.读Java性能权威指南(第2版)笔记26_性能测试方法下28.读Java性能权威指南(第2版)笔记27_线程和同步性能上29.读Java性能权威指南(第2版)笔记28_线程和同步性能中30.读Java性能权威指南(第2版)笔记29_线程和同步性能下31.读Java性能权威指南(第2版)笔记30_Java服务器1. 通用规则
1.1. 不要假设问题出在堆空间
1.2. 谨慎地创建对象并尽快丢弃它们
1.3. 使用更少的内存是提高垃圾回收器效率最好的办法
1.3.1. 减少内存使用是一个重要的目标
1.3.2. 和大多数性能优化主题一样,将精力集中于最大化利用现有内存会更有帮助
1.4. 对象重用方式
1.4.1. 线程局部变量
1.4.2. 特殊对象引用
1.4.3. 对象池
1.5. 重用对象意味着它们将长期存在并会影响垃圾回收器
1.5.1. 当它们被合理地重用时,整体性能将得到提升
2. 堆直方图
2.1. heap histogram
2.2. 快速查看应用程序中对象数量的方法,不需要生成完整堆转储
2.3. 用于识别由于某种特定类型的对象创建得太多而导致的内存问题
2.4. % jmap -histo process_id
2.5. % jmap -histo:live process_id
3. 堆转储
3.1. heap dump
3.2. 最强大的跟踪内存使用的技术
3.3. 常用工具
3.3.1. jvisualvm
3.3.1.1. 从正在运行的程序中获得堆转储文件
3.3.1.2. 可以打开之前生成的堆转储文件
3.3.1.3. 检查最大的保留对象并执行对堆的任意查询
3.3.2. 开源的Eclipse Memory Analyzer Tool
3.3.2.1. mat
3.3.2.2. 加载一个或者多个堆转储文件并对其进行分析
3.3.2.3. 可以产生报告
3.3.2.4. 可以用来浏览堆
3.3.2.5. 对堆执行类似SQL的查询
3.3.2.6. 提示可能出现问题的地方
3.4. % jcmd process_id GC.heap_dump /path/to/heap_dump.hprof
3.5. % jmap -dump:live,file=/path/to/heap_dump.hprof process_id
3.5.1. 包含live选项会在堆被转储之前强制执行Full GC
3.5.2. 如果因为某些原因你想包含其他的对象(死对象),可以在jcmd命令行的末尾加上-all
4. 内存分析
4.1. 对象的浅大小(shallow size)
4.1.1. 对象本身的大小
4.2. 对象的深大小(deep size)
4.2.1. 包含它所引用的对象的大小
4.3. 对象的深大小和保留大小的区别在于其引用的对象是否是共享的
4.4. 保留大量堆空间的对象通常被称为堆的支配者
4.5. 一般的经验法则是,寻找路径应该从集合对象(如HashMap)而不是从条目(如HashMap$Entry)开始,并且要寻找最大的集合
5. 内存溢出错误
5.1. out-of-memory
5.2. JVM没有可用的原生内存
5.2.1. 在Linux中,用户常常只被允许创建1024个进程
5.2.1.1. 可以通过运行ulimit-u来检查这个值
5.2.1.2. 试图创建第1025个线程,JVM就会抛出OutOfMemoryError异常
5.2.1.3. 操作系统对进程数量施加的限制导致的错误
5.2.2. 错误消息
5.2.2.1. Exception in thread "main" java.lang.OutOfMemoryError:unable to create new native thread
5.3. 元空间内存不足
5.3.1. 这个错误的发生通常是因为你设置了最大大小
5.3.1.1. 元空间默认情况下没有最大大小的限制
5.3.2. 根本原因
5.3.2.1. 分配的元空间已经放不下应用程序使用的类
5.3.2.2. 涉及类加载器的内存泄漏
5.3.2.2.1. 最常发生在动态加载类的服务器中
5.3.2.2.1.1. 增加元空间的大小会有帮助,但也只是推迟了错误发生的时间而已
5.3.2.2.1.2. 除了联系应用服务器厂商让他们修复内存泄漏问题之外,没有其他办法
5.3.3. 错误消息
5.3.3.1. Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
5.4. Java堆本身内存不足
5.4.1. 对于给定大小的堆,应用程序已经无法创建任何额外的对象
5.4.2. 错误消息
5.4.2.1. Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
5.5. -XX:+HeapDumpOnOutOfMemoryError
5.5.1. 打开这个标志会让JVM在抛出内存溢出错误时创建堆转储
5.5.2. 默认是false
5.6. -XX:HeapDumpPath=
5.6.1. 该标志指定堆转储的写入位置
5.6.1.1. 可以指定目录
5.6.1.1.1. 会使用默认文件名
5.6.1.2. 可以指定要生成的实际文件名
5.6.2. 默认位置是应用程序当前工作目录下的java_pid.hprof
5.7. -XX:+HeapDumpAfterFullGC
5.7.1. 运行Full GC之后生成堆转储
5.8. -XX:+HeapDumpBeforeFullGC
5.8.1. 运行Full GC之前生成堆转储
5.9. -XX:+ExitOnOutOfMemoryError
5.9.1. JVM在堆内存用尽时退出
5.9.2. 默认是false
5.10. JVM花费了太多时间执行GC
5.10.1. 错误消息
5.10.1.1. Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
5.11. -XX:GCTimeLimit=N
5.11.1. 在Full GC中花费的时间超过了指定值
5.11.2. 默认值是98
5.11.2.1. 98%的时间花在GC上,该条件就满足
5.12. -XX:GCHeapFreeLimit=N
5.12.1. 一次Full GC回收的内存量小于指定值
5.12.2. 默认值是2
5.12.2.1. Full GC期间回收的内存小于堆的2%,该条件就满足
5.13. -XX:+UseGCOverheadLimit
5.13.1. 前面两个条件在5个连续的Full GC周期中都成立
5.13.2. 默认值true
合集:
读Java性能权威指南(第2版)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库