内存溢出是什么?
当程序需要申请内存的时候,由于没有足够的内存,此时就会抛出OutOfMemoryError,这就是内存溢出。
内存溢出和内存泄漏有什么区别?
内存泄漏是由于使用不当,把一部分内存“丢掉了”,导致这部分内存不可用。
当在堆中创建了对象,后来没有使用这个对象了,又没有把整个对象的相关引用设为null。此时垃圾收集器会认为这个对象是需要的,就不会清理这部分内存。这就会导致这部分内存不可用。
所以内存泄漏会导致可用的内存减少,进而会导致内存溢出。
用到的jvm参数
下面为了说明溢出的情景,会执行一些实例代码,同时需要给jvm指定参数
- -Xms 堆最小容量(heap min size)
- -Xmx 堆最大容量(heap max size)
- -Xss 栈容量(stack size)
- -XX:PermSize=size 永生代最小容量
- -XX:MaxPermSize=size 永生代最大容量
一 堆溢出
java.lang.OutOfMemoryError: Java heap space
这个异常是由于堆中存在大量的对象,这些对象无法通过垃圾回收进行收集从而导致的堆内存溢出,堆溢出呢,分为两种情况:
- 内存泄露(大量无用的对象与根节点还具有管理,无法被回收)
- 对象过多
如何解决?
- 内存泄露情况可以通过工具找出泄露的具体代码然后进行优化
- 对象太多可以适当根据机器的性能使用-Xms -Xmx等参数调整堆的大小
- 优化数据结构,避免内存浪费
二 直接内存溢出
OutOfMemoryError
直接内存并不属于运行时数据区的一部分。但是也需要占用内存,如果我们在分配内存时把本机的总内存都分配给运行时数据区的各个部分而忽略了直接内存的话就会容易引起直接内存溢出。Java中使用直接内存最多的就是NIO。
如何解决?
- 使用-XX:MaxDirectMemorySize属性指定直接内存的大小
三 方法区溢出
java.lang.OutOfMemoryError: PermGen space
因为方法区主要是负责存放类的相关信息,而且因为gc的次数也不像堆来的频繁,所以当class越来越多的时候就会引起此异常
如何解决?
- 使用-XX:PermSize参数调整方法区的大小
四 虚拟机栈和本地方法栈(栈溢出)
StackOverflowError
由于线程请求的栈深度大于了线程所允许的最大深度而引起的
如何解决?
使用-Xss参数调整栈的大小
OutOfMemoryError: unable to create new native thread
当创建的线程多到栈的内存不足以支撑时就会引起此异常
如何解决?
使用-Xss参数调整栈的大小
五 Metaspace(元空间)
元空间这个东西,是在JDK8以后才存在的,JDK7及以前,只有永久代
元空间的存储位置是在计算机的内存当中,而永久的存储们置是在JVM的地堆中
JVM用元空间代替永久代的原因:
1随着操作系统的发展,计算机支持的内存从32位的最大2^32字节,变为64位的最大2^48字节。
2随着Java 在Web领域的发展,java程序变的得越来越大,需要加载的内容也越来越多,如果
使用永久代实现方法区,那么需要手动扩大堆的大小,而使用元空间之后,就可以直接存
储在内存当中,不用手动云修改堆的大小。
元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小:
-XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
-XX:MaxMetaspaceSize,最大空间,默认是没有限制的。
除了上面两个指定大小的选项以外,还有两个与 GC 相关的属性:
-XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
-XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集
大家应该大致了解了 JVM 的内存划分,也清楚了 JDK 8 中永久代向元空间的转换。不过大家应该都有一个疑问,就是为什么要做这个转换?所以,最后给大家总结以下几点原因:
1、字符串存在永久代中,容易出现性能问题和内存溢出。
2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
4、Oracle 可能会将HotSpot 与 JRockit 合二为一。
原文地址:https://www.cnblogs.com/shu-java-net/p/13545992.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。