日本无码动漫av专区JVM 无法对其自动回收

  • 首页
  • 免费观 看成人网站
  • 将粗大挺进邻居人妻
  • 亚洲国产成人AV线
  • 伊人狼人大蕉香AV
  • 行房时间短怎么治
  • 日本无码动漫av专区JVM 无法对其自动回收
    发布日期:2022-09-23 07:10    点击次数:64
    美国a片一级香蕉网日本无码动漫av专区

     在《Java诬捏机圭表》的章程里,除了才智计数器外,诬捏机内存的其他几个运行时区域都有发生 OutOfMemoryError 特殊的可能。

    本篇主要包括如下 OOM 的先容和示例:

    java.lang.StackOverflowError java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: GC overhead limit exceeded java.lang.OutOfMemoryError-->Metaspace java.lang.OutOfMemoryError: Direct buffer memory java.lang.OutOfMemoryError: unable to create new native thread java.lang.OutOfMemoryError:Metaspace java.lang.OutOfMemoryError: Requested array size exceeds VM limit java.lang.OutOfMemoryError: Out of swap space java.lang.OutOfMemoryError:Kill process or sacrifice child

    咱们常说的 OOM 特殊,其实是 Error

    一. StackOverflowError

    1.1 写个 bug

    public class StackOverflowErrorDemo {      public static void main(String[] args) {         javaKeeper();     }      private static void javaKeeper() {         javaKeeper();     } } 

    JVM 诬捏机栈是有深度的,在实践治安的时候会伴跟着入栈和出栈,上边的治安不错看到,main 治安实践后不竭的递归,晨夕把栈撑爆了

    Exception in thread "main" java.lang.StackOverflowError  at oom.StackOverflowErrorDemo.javaKeeper(StackOverflowErrorDemo.java:15) 

    1.2 原因分析

    无尽递归轮回调用(最常宽恕因),要技艺扎眼代码中是否有了轮回调用治安而无法退出的情况 实践了大批治安,导致线程栈空间亏损 治安内声明了海量的局部变量 native 代码有栈上分拨的逻辑,而况条目的内存还不小,比如 java.net.SocketInputStream.read0 会在栈上条目分拨一个 64KB 的缓存(64位 Linux)

    1.3 照拂决策

    诞生激励无尽递归调用的特殊代码, 通过才智抛出的特殊堆栈,找出不绝重迭的代码行,胶柱鼓瑟,诞生无尽递归 Bug 排查是否存在类之间的轮回依赖(当两个对象互相援用,在调用toString治安时也会产生这个特殊) 通过 JVM 启动参数 -Xss 增多线程栈内存空间, 某些平淡使用场景需要实践大批治安或包含大批局部变量,这时不错合适地耕种线程栈空间截止

    二. Java heap space

    Java 堆用于存储对象实例,咱们唯一不绝的创建对象,而况保证 GC Roots 到对象之间有可达旅途来幸免 GC 取销这些对象,那跟着对象数量的增多,总容量波及堆的最大容量截止后就会产生内存溢出特殊。

    Java 堆内存的 OOM 特殊是实质应用中最常见的内存溢出特殊。

    2.1 写个 bug

    /**  * JVM参数:-Xmx12m  */ public class JavaHeapSpaceDemo {      static final int SIZE = 2 * 1024 * 1024;      public static void main(String[] a) {         int[] i = new int[SIZE];     } } 

    代码试图分拨容量为 2M 的 int 数组,淌若指定启动参数 -Xmx12m,分拨内存就不够用,就一样于将 XXXL 号的对象,往 S 号的 Java heap space 里面塞。

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space  at oom.JavaHeapSpaceDemo.main(JavaHeapSpaceDemo.java:13) 

    2.2 原因分析

    请求创建一个超大对象,庸碌是一个大数组 超出预期的窥探量/数据量,庸碌是上游系统请求流量飙升,常见于各样促销/秒杀行为,不错结合业务流量筹算排查是否有尖状峰值 过度使用散伙器(Finalizer),该对象莫得立即被 GC 内存表现(Memory Leak),大批对象援用莫得开释,JVM 无法对其自动回收,常见于使用了 File 等资源莫得回收

    2.3 照拂决策

    针对大部分情况,庸碌只需要通过 -Xmx 参数调高 JVM 堆内存空间即可。淌若仍然莫得照拂,不错参考以下情况做进一步处理:

    淌若是超大对象,不错查验其合感性,比如是否一次性查询了数据库一道扫尾,而莫得做扫余数截止 淌若是业务峰值压力,不错接洽添加机器资源,大略做限流左迁。 淌若是内存表现,需要找到持有的对象,修改代码联想,比如关闭莫得开释的市欢

    口试官:说说内存走漏和内存溢出

    加送个常识点,三连的终将成为大神~~

    内存走漏和内存溢出

    内存溢出(out of memory),是指才智在肯求内存时,莫得满盈的内存空间供其使用,出现out of memory;比如肯求了一个 Integer,但给它存了 Long 才能存下的数,那便是内存溢出。

    内存走漏( memory leak),是指才智在肯求内存后,无法开释已肯求的内存空间,一次内存走漏危害不错忽略,但内存走漏堆积后果很严重,不管若干内存,晨夕会被占光。

    memory leak 最终会导致 out of memory!

    三、GC overhead limit exceeded

    JVM 内置了垃圾回收机制GC,是以动作 Javaer 的咱们不需要手工编写代码来进行内存分拨和开释,但是当 Java 进度破耗 98% 以上的时辰实践 GC,但只还原了不到 2% 的内存,且该动作连气儿重迭了 5 次,就会抛出 java.lang.OutOfMemoryError:GC overhead limit exceeded 诞妄(俗称:垃圾回收上面)。浮浅地说,便是应用才智照旧基本亏损了统共可用内存,99re热最新地址 GC 也无法回收。

    假如不抛出 GC overhead limit exceeded 诞妄,那 GC 计帐的那么一丢丢内存很快就会被再次填满,迫使 GC 再次实践,这样恶性轮回,CPU 使用率 100%,而 GC 没什么后果。

    3.1 写个 bug

    出现这个诞妄的实例,其实咱们写个无尽轮回,往 List 或 Map 加数据就会一直 Full GC,直到扛不住,这里用一个阻滞易发现的栗子。咱们往 map 中添加 1000 个元素。

    /**  * JVM 参数: -Xmx14m -XX:+PrintGCDetails  */ public class KeylessEntry {      static class Key {         Integer id;          Key(Integer id) {             this.id = id;         }          @Override         public int hashCode() {             return id.hashCode();         }     }      public static void main(String[] args) {         Map m = new HashMap();         while (true){             for (int i = 0; i < 1000; i++){                 if (!m.containsKey(new Key(i))){                     m.put(new Key(i), "Number:" + i);                 }             }             System.out.println("m.size()=" + m.size());         }     } } 
    ... m.size()=54000 m.size()=55000 m.size()=56000 Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded 

    从输出扫尾不错看到,咱们的截止 1000 条数据莫得起作用,map 容量远进步了 1000,而且临了也出现了咱们想要的诞妄,这是因为类 Key 只重写了 hashCode() 治安,却莫得重写 equals() 治安,咱们在使用 containsKey() 治安其实就出现了问题,于是就会一直往 HashMap 中添加 Key,直至 GC 都计帐不掉。

     口试官又来了:说一下HashMap旨趣以及为什么需要同期竣事equals和hashcode

    实践这个才智的最终诞妄,和 JVM 配置也会联系系,淌若建设的堆内存很是小,会径直报 Java heap space。算是被这个诞妄截胡了,是以未必,在资源受限的情况下,无法准确臆测才智会死于哪种具体的原因。

    3.2 照拂决策

    添加 JVM 参数-XX:-UseGCOverheadLimit 不推选这样干,莫得信得过照拂问题,仅仅将特殊推迟 查验技俩中是否有大批的死轮回或有使用大内存的代码,优化代码 dump内存分析,查验是否存在内存走漏,淌若莫得,加大内存

    四、Direct buffer memory

    咱们使用 NIO 的时候频频需要使用 ByteBuffer 来读取或写入数据,人妻无码视频大全这是一种基于 Channel(通道) 和 Buffer(缓冲区)的 I/O 姿首,它不错使用 Native 函数库径直分拨堆外内存,然后通过一个存储在 Java 堆里面的 DirectByteBuffer 对象动作这块内存的援用进行操作。这样在一些场景就幸免了 Java 堆和 Native 中来去应制数据,是以性能会有所耕种。

    Java 允许应用才智通过 Direct ByteBuffer 径直窥探堆外内存,许多高性能才智通过 Direct ByteBuffer 结合内存映射文献(Memory Mapped File)竣事高速 IO。

    4.1 写个 bug

    ByteBuffer.allocate(capability) 是分拨 JVM 堆内存,属于 GC 统领范畴,需要内存拷贝是以速率相对较慢; ByteBuffer.allocateDirect(capability) 是分拨 OS 土产货内存,不属于 GC 统领范畴,由于不需要内存拷贝是以速率相对较快;

    淌若不绝分拨土产货内存,堆内存很少使用,那么 JVM 就不需要实践 GC,DirectByteBuffer 对象就不会被回收,这时天然堆内存充足,但土产货内存可能照旧不够用了,就会出现 OOM,土产货径直内存溢出。

    /**  *  VM Options:-Xms10m,-Xmx10m,-XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m  */ public class DirectBufferMemoryDemo {      public static void main(String[] args) {         System.out.println("maxDirectMemory is:"+sun.misc.VM.maxDirectMemory() / 1024 / 1024 + "MB");          //ByteBuffer buffer = ByteBuffer.allocate(6*1024*1024);         ByteBuffer buffer = ByteBuffer.allocateDirect(6*1024*1024);      } } 

    最大径直内存,默许是电脑内存的 1/4,是以咱们设小点,然后使用径直内存进步这个值,就会出现 OOM。

    maxDirectMemory is:5MB Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory 

    4.2 照拂决策

    Java 只可通过 ByteBuffer.allocateDirect 治安使用 Direct ByteBuffer,因此,不错通过 Arthas 等在线会诊用具禁锢该治安进行排查 查验是否径直或蜿蜒使用了 NIO,如 netty,jetty 等 通过启动参数 -XX:MaxDirectMemorySize 鼎新 Direct ByteBuffer 的上限值 查验 JVM 参数是否有 -XX:+DisableExplicitGC 选项,淌若有就去掉,因为该参数会使 System.gc() 失效 查验堆外内存使用代码,证据是否存在内存表现;大略通过反射调用 sun.misc.Cleaner 的 clean() 治安来主动开释被 Direct ByteBuffer 持有的内存空间 内存容量如实不及,升级配置

    五、Unable to create new native thread

    每个 Java 线程都需要占用一定的内存空间,当 JVM 向底层操作系统请求创建一个新的 native 线程时,淌若莫得满盈的资源分拨就会报此类诞妄。

    5.1 写个 bug

    public static void main(String[] args) {   while(true){     new Thread(() -> {       try {         Thread.sleep(Integer.MAX_VALUE);       } catch(InterruptedException e) { }     }).start();   } } Error occurred during initialization of VM java.lang.OutOfMemoryError: unable to create new native thread 

    5.2 原因分析

    JVM 向 OS 请求创建 native 线程失败,就会抛出 Unableto createnewnativethread,常见的原因包括以下几类: 线程数进步操作系统最大线程数截止(和平台联系) 线程数进步 kernel.pid_max(只可重启) native 内存不及;该问题发生的常见过程主要包括以下几步: JVM 里面的应用才智请求创建一个新的 Java 线程; JVM native 治安代理了该次请求,并向操作系统请求创建一个 native 线程; 操作系统尝试创建一个新的 native 线程,并为其分拨内存; 淌若操作系统的诬捏内存已亏损,或是受到 32 位进度的地址空间截止,操作系统就会拆开本次 native 内存分拨; JVM 将抛出 java.lang.OutOfMemoryError:Unableto createnewnativethread 诞妄。

    5.3 照拂决策

    想方针裁汰才智中创建线程的数量,分析应用是否竟然需要创建这样多线程

    淌若如实需要创建好多线程,调高 OS 层面的线程最大数:实践 ulimia-a 稽察最大线程数截止,使用 ulimit-u xxx 鼎新最大线程数截止

    六、Metaspace

    JDK 1.8 之前会出现 Permgen space,该诞妄暗意恒久代(Permanent Generation)已用满,庸碌是因为加载的 class 数量太多或体积太大。跟着 1.8 中恒久代的取消,就不会出现这种特殊了。

    Metaspace 是治安区在 HotSpot 中的竣事,它与恒久代最大的分歧在于,元空间并不在诬捏机内存中而是使用土产货内存,但是土产货内存也有打满的时候,是以也会有特殊。

    6.1 写个 bug

    /**  * JVM Options: -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m  */ public class MetaspaceOOMDemo {      public static void main(String[] args) {          while (true) {             Enhancer enhancer = new Enhancer();             enhancer.setSuperclass(MetaspaceOOMDemo.class);             enhancer.setUseCache(false);             enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {                 //动态代理创建对象                 return methodProxy.invokeSuper(o, objects);             });             enhancer.create();         }     } } 

    借助 Spring 的 GCLib 竣事动态创建对象

    Exception in thread "main" org.springframework.cglib.core.CodeGenerationException: java.lang.OutOfMemoryError-->Metaspace 

    6.2 照拂决策

    治安区溢出亦然一种常见的内存溢出特殊,在频频运行时生成大批动态类的应用场景中,就应该很是随和这些类的回收情况。这类场景除了上边的 GCLib 字节码增强和动态话语外,常见的还有,大批 JSP 或动态产生 JSP 文献的应用(旷古时间的传统软件行业可能会有)、基于 OSGi 的应用(即使合并个类文献,被不同的加载器加载也会视为不同的类)等。

    治安区在 JDK8 中一般不太容易产生,HotSpot 提供了一些参数来建设元空间,不错起到防患作用

    -XX:MaxMetaspaceSize 建设元空间最大值,默许是 -1,暗意不截止(照旧要受土产货内存大小截止的) -XX:MetaspaceSize 指定元空间的驱动空间大小,以字节为单元,达到该值就会触发 GC 进行类型卸载,同期采集器会对该值进行鼎新 -XX:MinMetaspaceFreeRatio 在 GC 之后限度最小的元空间剩余容量的百分比,可减少因元空间不及导致的垃圾采集频率,一样的还有 MaxMetaspaceFreeRatio

    七、Requested array size exceeds VM limit

    7.1 写个 bug

    public static void main(String[] args) {   int[] arr = new int[Integer.MAX_VALUE]; } 

    这个相比浮浅,建个超等大数组就会出现 OOM,未几说了

    Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit 

    JVM 截止了数组的最大长度,该诞妄暗意才智请求创建的数组进步最大长度截止。

    JVM 在为数组分拨内存前,会查验要分拨的数据结构在系统中是否可寻址,庸碌为 Integer.MAX_VALUE-2。

    此类问题相比冷落,庸碌需要查验代码,证据业务是否需要创建如斯大的数组,是否不错拆分为多个块,分批实践。

    八、Out of swap space

    启动 Java 应用才智会分拨有限的内存。此截止是通过-Xmx和其他一样的启动参数指定的。

    在 JVM 请求的总内存大于可用物理内存的情况下,操作系统出手将内容从内存换出到硬盘驱动器。

    该诞妄暗意统共可用的诬捏内存已被亏损。诬捏内存(Virtual Memory)由物理内存(Physical Memory)和交换空间(Swap Space)两部分构成。

    这种诞妄没见过~~~

    九、Kill process or sacrifice child

    操作系统是建立在历程看法之上的。这些进度由几个内核功课崇拜,其中一个名为“ Out of memory Killer”,它会在可用内存极低的情况下“杀死”(kill)某些进度。OOM Killer 会对统共进度进行打分,然后将评分较低的进度“杀死”,具体的评分规定不错参考 Surviving the Linux OOM Killer。

    不同于其他的 OOM 诞妄, Killprocessorsacrifice child 诞妄不是由 JVM 层面触发的,而是由操作系统层面触发的。

    9.1 原因分析

    默许情况下,Linux 内核允许进度肯求的内存总量大于系统可用内存,通过这种“错峰复用”的姿首不错更有用的诈欺系统资源。

    但是,这种姿首也会无可幸免地带来一定的“超卖”风险。举例某些进度持续占用系统内存,然后导致其他进度莫得可用内存。此时,系统将自动激活 OOM Killer,寻找评分低的进度,并将其“杀死”,开释内存资源。

    9.2 照拂决策

    升级干事器配置/进攻部署,幸免争用 OOM Killer 调优。

    临了附上一张“涯海”大神的图

    《真切解析 Java 诬捏机 第 3 版》

    https://plumbr.io/outofmemoryerror

    https://yq.aliyun.com/articles/711191

    https://github.com/StabilityMan/StabilityGuide/blob/master/docs/diagnosis/jvm/exception

    本文转载自微信公众号「JavaKeeper」,作家海星 。转载本文请联系 JavaKeeper公众号。

     

    原文筹划:https://mp.weixin.qq.com/s/gIJvtd8rrZz6ttaoGLddLg