栈内存--虚拟机栈、本地方法栈溢出-----以Hotspot虚拟机为例

一、栈内存参数

     -Xss 

二、栈溢出的两种情况

    2.1 如果线程请求的栈深度大于虚拟机允许的最大深度时,抛出StackOverflowError异常

    2.2 如果虚拟机在扩展栈时,无法申请到足够的空间,则抛出OutOfMemoryError异常

三、StackOverflowError异常

    3.1  代码

栈内存--虚拟机栈、本地方法栈溢出-----以Hotspot虚拟机为例_第1张图片

   3.2  虚拟机栈深度为:18545  抛出StackOverFlowError异常

   栈内存--虚拟机栈、本地方法栈溢出-----以Hotspot虚拟机为例_第2张图片

四   OutOfMemoryError异常

    4.1 代码 模拟多线程 

    栈内存--虚拟机栈、本地方法栈溢出-----以Hotspot虚拟机为例_第3张图片

   4.2  异常

    栈内存--虚拟机栈、本地方法栈溢出-----以Hotspot虚拟机为例_第4张图片


    特别提醒:由于java虚拟机线程会映射到操作系统的内核线程中,  在模拟多线程 导致栈内存OOM异常,会造成操作系统假死,抛出异常后,我电脑变得异常慢 。。。。慢。。。。。 谨慎使用

   五、栈内存的性能调优思路

      操作系统分配给每个进程的内存是有限制的, 譬如32位的Windows限制为2GB。 虚拟机提供了参数来控制Java堆和方法区的这 两部分内存的最大值。 剩余的内存为2GB(操作系统限制)减去Xmx(最大堆容量), 再减去MaxPermSize( 最大方法区容量), 程序计数器消耗内存很小,可以忽略掉。

      如果 虚拟 机 进程 本身 耗费 的 内存 不计 算在 内, 剩下 的 内存 就 由 虚拟 机 栈 和 本地 方法 栈“ 瓜分” 了。 每个 线程 分配 到 的 栈 容量 越大, 可以 建立 的 线程 数量 自然 就 越少, 建立 线程 时 就 越 容易 把 剩下 的 内存 耗尽。

     这一点 读者 需要 在 开发 多 线程 的 应用 时 特别 注意, 出现 StackOverflowError 异常 时有 错误 堆栈 可以 阅读, 相对来说, 比较 容易 找到 问题 的 所在。 而且, 如果 使用 虚拟 机 默认 参数, 栈 深度 在 大多数 情况下( 因为 每个 方法 压 入栈 的 帧 大小 并不是 一样 的, 所以 只 能说 在 大多数 情况下) 达到 1000 ~ 2000 完全 没有 问题, 对于 正常 的 方法 调用( 包括 递归), 这个 深度 应该 完全 够用 了。 但是, 如果 是 建立 过多 线程 导致 的内存 溢出, 在 不能 减少 线程 数 或者 更换 64 位 虚拟 机 的 情况下, 就 只能 通过 减少 最 大堆 和 减少 栈 容量 来 换取 更多 的 线程。 如果 没有 这 方面 的 处理 经验, 这种 通过“ 减少 内存” 的 手段 来 解决 内存 溢出 的 方式 会 比较 难以 想到。


     



你可能感兴趣的:(java虚拟机)