-
本地方法栈和虚拟机栈溢出
2020-03-22 16:53:381)如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。 2)如果虚拟机的栈内存允许动态扩展,当扩展栈容量无法申请到足够的内存时,将抛出OutOfMemoryError异常。 《Java虚拟机规范...1)如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。
2)如果虚拟机的栈内存允许动态扩展,当扩展栈容量无法申请到足够的内存时,将抛出OutOfMemoryError异常。
《Java虚拟机规范》明确允许Java虚拟机实现自行选择是否支持栈的动态扩展,而HotSpot虚拟机的选择是不支持扩展,所以除非在创建线程申请内存时就因无法获得足够内存而出现OutOfMemoryError异常,否则在线程运行时是不会因为扩展而导致内存溢出的,只会因为栈容量无法容纳新的栈帧而导致StackOverflowError异常。
-
Java虚拟机OOM之虚拟机栈和本地方法栈溢出(4)
2015-04-14 19:05:26一、在 Java 虚拟机规范中,对虚拟机栈这个区域规定了两种异常状况:(1)如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError 异常; (2)如果虚拟机栈可以动态扩展(当前大部分的 Java ...一、在 Java 虚拟机规范中,对虚拟机栈这个区域规定了两种异常状况:
(1)如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError 异常;
(2)如果虚拟机栈可以动态扩展(当前大部分的 Java 虚拟机都可动态扩展,只不过 Java 虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出 OutOfMemoryError 异常。
(3)与虚拟机栈一样,本地方法栈区域也会抛出 StackOverflowError 和OutOfMemoryError 异常。二、前一篇文章中的第一张图也看出来了对于虚拟机栈和本地方法栈 如果在多线程的情况下是可能出现OOM的,下边就是一个单线程的案例。演示一下:
/** * 设置 VM Args: -Xss128k * @author xuliugen * */ public class JavaVMStackSOF { private int stackLength = 1; //反复调用 public void stackLeak() { stackLength++; stackLeak(); } public static void main(String[] args) throws Throwable { JavaVMStackSOF oom = new JavaVMStackSOF(); try { oom.stackLeak(); } catch (Throwable e) { System.out.println("stack length:" + oom.stackLength); throw e; } } }
要设置VM Args: -Xss128k(上一篇已经说到:设置栈为128k),结果如下:
stack length:40550 Exception in thread "main" java.lang.StackOverflowError at com.lc.oom.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:8) 后续很多异常省略。。。
结果表明:在单个线程下,无论是由于栈帧太大,还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是 StackOverflowError 异常,而不是OOM。
三、如果测试时不限于单线程,通过不断地建立线程的方式倒是可以产生内存溢出异常。自己可以创建多个线程,进行测试,但是:由于在Windows 平台的虚拟机中, Java 的线程是映射到操作系统的内核线程上的,所以多线程代码执行时有较大的风险,可能会导致操作系统假死。所以。。。
不过结果肯定是,多线程的情况下,是会出现OOM的!
原理如下:
为什吗多线程的情况下就会产生OOM,这样产生的内存溢出异常与栈空间是否足够大并不存在任何联系,或者准确地说,在这种情况下,给每个线程的栈分配的内存越大,反而越容易产生内存溢出异常。
原因其实不难理解,操作系统分配给每个进程的内存是有限制的,譬如 32 位的 Windows 限制为 2GB。虚拟机提供了参数来控制 Java 堆和方法区的这两部分内存的最大值。剩余的内存为 2GB(操作系统限制)减去 Xmx(最大堆容量),再减去 MaxPermSize(最大方法区容量),程序计数器消耗内存很小,可以忽略掉。如果虚拟机进程本身耗费的内存不计算在内,剩下的内存就由虚拟机栈和本地方法栈“瓜分”了。每个线程分配到的栈容量越大,可以建立的线程数量自然就越少,建立线程时就越容易把剩下的内存耗尽。
更简单理解的就是:有一个操作系统为2G,我们分配给两个线程,每个800M,也就还剩400M,这样的话,有一个线程不够用的话,就会在400里边申请,所以如果剩下的越多,出现OOM的可能性越小,如果每个分配950M,这样就剩100M,这样的话出现OOM的可能性就更大。如果在增加线程,系统对每一个线程非配的内存是一定的,所以剩下的内存更少,这样的话,出现OOM的可能更大,但这都是相对而说。
遇到OOM这时候我们应该怎么做:
如果是建立过多线程导致的内存溢出,在不能减少线程数或者更换 64 位虚拟机的情况下,就只能通过减少最大堆和减少栈容量来换取更多的线程。如果没有这方面的经验,这种通过“减少内存”的手段来解决内存溢出的方式会比较难以想到。这种拆东墙补西墙的方法,还是自己意会吧。
-
Java虚拟机OOM之虚拟机栈和本地方法栈溢出
2018-06-05 10:52:27一、在 Java 虚拟机规范中,对虚拟机栈这个区域规定了两种异常状况:(1)如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError 异常; (2)如果虚拟机栈可以动态扩展(当前大部分的 Java ...一、在 Java 虚拟机规范中,对虚拟机栈这个区域规定了两种异常状况:
(1)如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError 异常;
(2)如果虚拟机栈可以动态扩展(当前大部分的 Java 虚拟机都可动态扩展,只不过 Java 虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出 OutOfMemoryError 异常。
(3)与虚拟机栈一样,本地方法栈区域也会抛出 StackOverflowError 和OutOfMemoryError 异常。二、前一篇文章中的第一张图也看出来了对于虚拟机栈和本地方法栈 如果在多线程的情况下是可能出现OOM的,下边就是一个单线程的案例。演示一下:
/** * 设置 VM Args: -Xss128k * */ public class JavaVMStackSOF { private int stackLength = 1; //反复调用 public void stackLeak() { stackLength++; stackLeak(); } public static void main(String[] args) throws Throwable { JavaVMStackSOF oom = new JavaVMStackSOF(); try { oom.stackLeak(); } catch (Throwable e) { System.out.println("stack length:" + oom.stackLength); throw e; } } }
要设置VM Args: -Xss128k(上一篇已经说到:设置栈为128k),结果如下:
stack length:40550 Exception in thread "main" java.lang.StackOverflowError at com.lc.oom.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:8) 后续很多异常省略。。。
结果表明:在单个线程下,无论是由于栈帧太大,还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是 StackOverflowError 异常,而不是OOM。
三、如果测试时不限于单线程,通过不断地建立线程的方式倒是可以产生内存溢出异常。自己可以创建多个线程,进行测试,但是:由于在Windows 平台的虚拟机中, Java 的线程是映射到操作系统的内核线程上的,所以多线程代码执行时有较大的风险,可能会导致操作系统假死。所以。。。
不过结果肯定是,多线程的情况下,是会出现OOM的!
原理如下:
为什吗多线程的情况下就会产生OOM,这样产生的内存溢出异常与栈空间是否足够大并不存在任何联系,或者准确地说,在这种情况下,给每个线程的栈分配的内存越大,反而越容易产生内存溢出异常。
原因其实不难理解,操作系统分配给每个进程的内存是有限制的,譬如 32 位的 Windows 限制为 2GB。虚拟机提供了参数来控制 Java 堆和方法区的这两部分内存的最大值。剩余的内存为 2GB(操作系统限制)减去 Xmx(最大堆容量),再减去 MaxPermSize(最大方法区容量),程序计数器消耗内存很小,可以忽略掉。如果虚拟机进程本身耗费的内存不计算在内,剩下的内存就由虚拟机栈和本地方法栈“瓜分”了。每个线程分配到的栈容量越大,可以建立的线程数量自然就越少,建立线程时就越容易把剩下的内存耗尽。
更简单理解的就是:有一个操作系统为2G,我们分配给两个线程,每个800M,也就还剩400M,这样的话,有一个线程不够用的话,就会在400里边申请,所以如果剩下的越多,出现OOM的可能性越小,如果每个分配950M,这样就剩100M,这样的话出现OOM的可能性就更大。如果在增加线程,系统对每一个线程非配的内存是一定的,所以剩下的内存更少,这样的话,出现OOM的可能更大,但这都是相对而说。
遇到OOM这时候我们应该怎么做:
如果是建立过多线程导致的内存溢出,在不能减少线程数或者更换 64 位虚拟机的情况下,就只能通过减少最大堆和减少栈容量来换取更多的线程。如果没有这方面的经验,这种通过“减少内存”的手段来解决内存溢出的方式会比较难以想到。这种拆东墙补西墙的方法,还是自己意会吧。
文章更多来自:点击打开链接
-
虚拟机栈和本地方法栈溢出
2019-06-09 15:42:00由于HotSpot虚拟机中并不区分虚拟机栈和本地方法栈,因此,虽然设置本地方法栈大小的参数 (-Xoss)存在,但是无效,栈容量只能由-Xss参数...如果虚拟机在扩展栈时无法申请到足够内存空间,则抛出OutOfMemoryError...由于HotSpot虚拟机中并不区分虚拟机栈和本地方法栈,因此,虽然设置本地方法栈大小的参数
(-Xoss)存在,但是无效,栈容量只能由-Xss参数设定。关于虚拟机栈和本地方法栈溢,在java虚拟机规范中描述了两种异常:
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常
如果虚拟机在扩展栈时无法申请到足够内存空间,则抛出OutOfMemoryError异常
虽然分成两种情况,但是这两者也有一些共同之处:当栈空间无法继续分配时,到底是内存大小,还是已使用的栈空间太大,其本质上只是对同一件事情的两种描述。
在实例中,将实验范围限制于单线程中的操作。
分为两种情况:
使用-Xss参数减少栈内存容量。结果抛出异常,异常出现时输出的堆栈深度相应缩小。
定义了大量的本地变量,增大此方法帧中本地变量表的长度。结果抛出异常,输出的堆栈深度相应缩小。public class JavaVMStackSOF{ private int stackLength = 1; public void stackLeak(){ stackLength++; stackLeak(); public static void main(String[] args) throws Throwable{ JavaVMStackSOF oom = new JavaVMStackSOF; try{ oom.stackLeak(); }catch(Throwable e){ System.out.println("stack length:" + oom.stackLength); throw e; } } } }
运行结果:
Exception in thread "main" java.lang.StackOverflowError
-
深入JVM 虚拟机栈和本地方法栈溢出
2019-02-20 22:54:33由于在HotSpot虚拟机中不区分虚拟机栈和本地方法栈,因此,对于HotSpot而言,-Xoss设置本地方法栈的参数失效 ,栈的容量大小只有Xss参数设置。虚拟机栈主要出现2种错误异常 如果线程请求的栈深度大于虚拟机栈所... -
java虚拟机栈和本地方法栈溢出
2016-10-25 14:20:361、HotSpot虚拟机中并不...1、如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。 2、如果虚拟机在扩展时无法申请到足够的内存空间,则抛出OutofMemoryError异常。 测试:StackOve -
【JVM】Java虚拟机中的本地方法栈
2020-09-12 10:51:24本地方法栈 ...如果本地方法栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的本地方法栈,那么Java虚拟机将会抛出一个outofMemoryError -
OutOfMemoryError异常——虚拟机栈和本地方法栈溢出。
2018-03-28 15:15:27由于在HotSpot虚拟机中并不区分虚拟机栈和本地方法栈,因此,对于HotSpot来说,虽然-...如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。 如果虚拟机在扩展栈时无法申请到足够的内... -
java基础——java虚拟机栈与本地方法栈
2018-09-30 16:41:10java虚拟机栈: 虚拟机栈描述的是java方法执行的内存模型,每个方法在...在java虚拟机规范中,对这个区域规定了两种异常状态,:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常,如... -
第二章:Java虚拟机栈和本地方法栈溢出
2019-03-29 00:17:00由于在Hotspot虚拟机中中不区分虚拟机栈和本地方法栈,因此通过-Xoss修改参数是无效的,可以通过修改-Xss设定。 如果线程请求的栈深度大于虚拟机允许的最大深度,将抛出StackOverflowError异常。 如果虚拟机在... -
栈内存--虚拟机栈、本地方法栈溢出-----以Hotspot虚拟机为例
2018-01-31 22:11:422.1 如果线程请求的栈深度大于虚拟机允许的最大深度时,抛出StackOverflowError异常 2.2 如果虚拟机在扩展栈时,无法申请到足够的空间,则抛出OutOfMemoryError异常 三、StackOverflowError异常 3.1 代码 ... -
.Net Core项目发布到虚拟机(三)
2018-09-11 14:34:00在上一集我们说到 已经做好项目并连接到本地的mysql可以进行增删改了,接下里我们将这个项目发布到我们的虚拟机上运行... ps:简单给出一张view视图页面,并用jquery发出请求 注意:1.在项目文件夹里找到.... -
JVM程序计数器,虚拟机栈,本地方法栈
2020-10-19 23:26:43java虚拟机是多线程通过轮流切换CPU时间片的方式实现,在同一时间内,CPU只会执行一个线程中的一个指令,为了每次切换回来都能到正确的执行位置,每个线程都会有一个独立的线程计数器,每个计数器不会相互影响,并且是... -
jvm_内存溢出_虚拟机栈和本地方法栈溢出
2015-03-11 21:49:04关于虚拟机栈和本地方法栈,在Java虚拟机规范中描述了两种异常: 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。 如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出... -
Java虚拟机
2020-09-01 09:23:41记录正在执行的Java虚拟机字节码指令的地址(如果正在执行的是本地方法,则为空)。 Java虚拟机栈 每个Java方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作符栈、常量池引用等信息。从方法调用直至执行... -
JVM学习笔记-虚拟机栈和本地方法栈溢出
2011-10-12 16:48:02关于虚拟机栈和本地方法栈,在JAVA虚拟机规范中描述了两种异常: 1.如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常:个人感觉应该分为栈深度导致,及该线程所用栈内空间溢出所致。... -
java虚拟机栈和本地方法栈内存溢出的原因现象以及解决思路
2019-12-12 19:57:08java虚拟机栈和本地方法栈都是描述方法执行的内存模型,每个方法在执行的同时,都会创建一个栈帧,栈帧用于存储局部变量表等信息。每个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈 的过程... -
OutOfMemoryError/OOM/内存溢出异常实例分析--虚拟机栈和本地方法栈溢出
2018-10-26 10:21:00关于虚拟机栈和本地方法栈,在JVM...2.如果虚拟机在扩展栈时无法申请到足够的内存,就会抛出OutOfMemoryError异常。 下面进行虚拟机栈和本地方法栈的SOF异常测试: public class JavaVMStackSOF { private ... -
安卓模拟器请求本地资源,不修改hosts
2021-03-04 16:46:28web服务器在本地的homestead里面,192.168.10.10,本机的地址是...安卓模拟器应该也是在2.x的这个网段,所以没有办法请求到虚拟机(10.10);所以使用charles做一个反向代理;然后在模拟器的setting中配置如下: ... -
java 栈溢出异常_JVM【第六回】:【OutOfMemoryError异常之虚拟机栈和本地方法栈溢出】...
2021-02-28 15:51:59关于虚拟机栈和本地方法栈,在Java规范中描述了两种异常:如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMem... -
深入理解Java虚拟机一
2018-11-26 09:47:02虚拟机栈与本地方法栈溢出 Java虚拟机规范中描述了两种异常: 1 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。 2如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出... -
实现主机访问虚拟机netbox-docker
2020-08-01 16:29:34文章目录本地环境个人需求获取主机和虚拟机的网卡信息获取主机的...把外部请求从宿主机转发到虚拟机内的linux处理,宿主机开放端口8080,linux开放端口8000(netbox-docker已经可以从虚拟机的0.0.0.0:8000访问),li -
虚拟机部署sentinel报Failed to fetch metric
2021-02-13 10:36:17我在本地启动了2个微服务,然后在虚拟机上面部署了sentinel控制台,当我发送请求以后在sentinel控制台并没有任何请求记录, 后我就去查找原因,我的本地的ip是192.168.0.103,虚拟机ip是192.168.0.105, 报错信息...