b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

jvm溢出

电脑杂谈  发布时间:2020-08-12 11:16:03  来源:网络整理

网页堆栈溢出_内存堆栈溢出_什么是堆栈溢出

import java.util.*;    
import java.lang.*;    
public class OOMTest{    
        public static void main(String... args){    
                List<byte[]> buffer = new ArrayList<byte[]>();    
                buffer.add(new byte[10*1024*1024]);    
        }    
}    

我们通过以下命令运行以上代码:

java -verbose:gc -Xmn10M -Xms20M -Xmx20M -XX:+PrintGC OOMTest

程序输出以下信息:

[GC 1180K->366K(19456K), 0.0037311 secs]    
[Full GC 366K->330K(19456K), 0.0098740 secs]    
[Full GC 330K->292K(19456K), 0.0090244 secs]    
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space    
        at OOMTest.main(OOMTest.java:7)    

网页堆栈溢出_内存堆栈溢出_什么是堆栈溢出

从运行结果可以看出,JVM执行了两次Minor gc和一次Major gc. 从Major gc的输出中可以看出,gc之后的旧区域的使用率为134K,字节数组为10M,加起来大于旧一代的空间,因此引发异常. 如果您调整-Xms21M,-Xmx21M,则不会触发gc操作,并且不会有异常.

上面的实验实际上从侧面验证了一个结论: 当对象大于新一代的剩余内存时,它将直接放置在旧一代中. 当仍然无法放下旧一代的剩余内存时,将触发垃圾回收. 如果您不能放下它,则会引发内存溢出异常.

永久性频带溢出(OutOfMemoryError: PermGen空间)

我们知道Hotspot jvm通过持久性磁带在Java虚拟机规范中实现了方法区域,并且运行时常量池存储在方法区域中,因此持久性磁带溢出可能是运行时常量池溢出,也可能是be方法区域中存储的类对象没有及时回收,或者类信息占用的内存超出了我们的配置.

当永久性磁带溢出时,抛出java.lang.OutOfMemoryError: PermGen空间. 它可能出现在以下情况下:

内存堆栈溢出_网页堆栈溢出_什么是堆栈溢出

使用某些应用程序服务器的热部署时,经过几次热部署后,我们将遇到内存溢出. 这是因为在每次热部署后都不会卸载原始类. 如果应用程序本身相对较大并且包含更多的类库,但是当内存相对较小时,也可能会出现分配给持久性磁带的内存(由-XX: PermSize和-XX: MaxPermSize设置). 一些第三方框架(例如spring和hibernate)通过字节码生成技术(例如CGLib)实现了一些增强的功能. 在这种情况下,可能需要更大的方法区域来存储动态生成的Class文件.

我们知道Java中的字符串常量位于常量池中. 当String.intern()方法运行时,它将检查常量池中是否存在与此字符串相等的对象,如果存在与该字符串相等的对象,则将直接返回常量. 的对象在池中不存在,请首先将字符串添加到常量池中,然后返回该字符串的引用. 然后,我们可以使用String.intern方法在运行时模拟常量区域的溢出. 下面,我们使用以下代码来模拟这种情况:

import java.util.*;    
import java.lang.*;    
public class OOMTest{    
        public static void main(String... args){    
                List list = new ArrayList();    
                while(true){    
                        list.add(UUID.randomUUID().toString().intern());    
                }    
        }        
}    

我们通过以下命令运行以上代码:

java -verbose:gc -Xmn5M -Xms10M -Xmx10M -XX:MaxPermSize=1M -XX:+PrintGC OOMTest

网页堆栈溢出_什么是堆栈溢出_内存堆栈溢出

运行后的输入如下图所示:

Exception in thread "main" java.lang.OutOfMemoryError: PermGen space    
        at java.lang.String.intern(Native Method)    
        at OOMTest.main(OOMTest.java:8)   

通过以上代码,我们在运行时成功模拟了常量池的溢出. 从输出中的PermGen空间可以看出,持久性区域确实溢出了. 这也验证了我们前面提到的Hotspot jvm通过了持久化带来的实现方法领域.

OutOfMemoryError: 无法创建本机线程

最后,让我们看一下错误java.lang.OutOfMemoryError: 无法创建natvie线程. 发生这种情况时,通常是由以下两种情况引起的:

网页堆栈溢出_什么是堆栈溢出_内存堆栈溢出

程序创建的线程数超过了操作系统的限制. 对于Linux系统,我们可以使用ulimit -u查看此限制. 分配给虚拟机的内存太大,导致创建线程时所需的本地内存太少.

我们都知道操作系统对每个进程的内存都有限制. 我们启动Jvm,这等效于启动一个进程. 如果一个进程占用4G内存,则通过以下公式计算的剩余内存是创建线程堆栈时可以使用的内存. 线程堆栈的可用总内存= 4G-(-Xmx的值)-(-XX的值: MaxPermSize)-程序计数器占用的内存

从上面的公式中,我们可以看到-Xmx和MaxPermSize的值越大,线程堆栈可用的空间越小. 在由-Xss参数配置的堆栈容量保持不变的情况下,可以创建它. 线程数也较小. 因此,如果由于这种情况无法创建本机线程,则我们要么增加进程占用的总内存,要么减少-Xmx或-Xss来达到创建更多线程的目的.

(本文结尾)

参考:

-

-


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-297350-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...