java-虚拟机-内存溢出
内存划分
1. 运行时数据区
- 堆 可能划分出多个线程私有的分配缓冲区tlab 在使用完tlab时会分配新的tlab这期间申请内存会同步锁定
- 虚拟机栈
- 本地方法栈 会抛出stackOverFlowError/OutOfMemoryError
- 方法区 存储虚拟机加载的类信息/常量/静态常量/及时编译后的代码
运行时常量池 是方法区的一部分,存放编译期生成的字面量/符号引用 并非编译期/预置入class文件中常量池的内容才能进入 运行期间调用intern()方法也会 会抛出OutOfmemoryError
- 程序计数器(唯一一个没有outOfMemoryError的区域)
2. 非运行时数据区
- 直接内存
对象的创建
1. 遇见new指令 根据指令的参数首先去常量池中定位到一个类符号引用 检查符号引用代表的类是否被加载 解析 初始化过
2. 类加载检查通过后 分配内存
3. 初始化0值
4. 显示初始化
内存区域溢出
堆溢出
通过参数-XX:+HeapDumpOnOutOfMemoryError 内存溢出时dump出当时的内存快照
栈溢出/本地方法栈溢出
1.当栈深度大于虚拟机运行的栈深度会抛出StackOverFlowError
2. 在扩展时无法申请到足够的内存空间抛出OutOfMemoryError
当单线程时只会抛出StackOverFlowError
多线程时会抛出OutOfMemoryError 操作系统给进程分配的内存大小是固定的,jvm通过xmx控制最大堆容量 MaxPermSize控制最大方法区容量 程序计数器太小可以忽略 剩下的就由虚拟机栈和本地方法栈瓜分
如果是过多的线程导致内存溢出,在不能减少线程数和更换内存的情况下,只能减少堆或减少栈容量来换取更多的线程
方法区
1. 方法区中存储class的相关信息,导致溢出的情况是运行时产生大量的类
使用cglib创建过多代理类会导致方法区溢出
大量jsp文件或者动态产生jsp文件的应用(jsp在第一次运行时需要编译成java文件)
直接内存
可以通过-XX:MaxDirectMemorySize指定默认使用java堆最大值
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2021-05-06 tcp/ip-三次握手/四次挥手