• 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堆最大值

  • 相关阅读:
    网站的安全架构
    Charles Proxy for Mac & Windows (4.1.3)破解激活工具
    charles抓包工具的中文乱码解决方法
    Charles 从入门到精通
    go语言知识点
    Golang Import使用入门
    算法图解之选择排序
    算法图解之数组和链表
    算法图解之大O表示法
    算法图解之内存的工作原理
  • 原文地址:https://www.cnblogs.com/isnotnull/p/16226575.html
Copyright © 2020-2023  润新知