账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    jvm内存不足导致应用僵死问题咨询
    47
    0

    页面上操作无反应 应用好像僵死

    在服务器上执行Top

      PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
     2299 root      20   0 2621076 727936  16544 S 99.9 38.6  67:08.05 java
     

    看到CPU100% 都是mongo 查询和插入的操作 没有计算密集型的操作 怎么会CPU100%呢

    jstack看到的几乎都是BLOCKED状态

    Thread 21304: (state = BLOCKED)
    

    查看 jmap -heap 2299

    Heap Usage:
    New Generation (Eden + 1 Survivor Space):
       capacity = 144703488 (138.0MB)
       used     = 132853872 (126.69932556152344MB)
       free     = 11849616 (11.300674438476562MB)
       91.81110547936481% used
    Eden Space:
       capacity = 128647168 (122.6875MB)
       used     = 128647168 (122.6875MB)
       free     = 0 (0.0MB)
       100.0% used
    From Space:
       capacity = 16056320 (15.3125MB)
       used     = 4206704 (4.0118255615234375MB)
       free     = 11849616 (11.300674438476562MB)
       26.199677136479593% used
    To Space:
       capacity = 16056320 (15.3125MB)
       used     = 0 (0.0MB)
       free     = 16056320 (15.3125MB)
       0.0% used
    tenured generation:
       capacity = 321585152 (306.6875MB)
       used     = 244174704 (232.86314392089844MB)
       free     = 77410448 (73.82435607910156MB)
       75.92847570275882% used
    

    怀疑是内存不足导致应用僵死
    为什么会僵死 而不是直接抛内存溢出(OutOfMemory)异常呢?为什么CPU会100%呢?

    0
    打赏
    收藏
    点击回答
        全部回答
    • 共 0 条
    • 可人的小仙女 VIP会员 1楼

      JVM内存不足(也称为Java Heap Underflow)是Java程序中常见的一种问题,它可能导致应用在运行过程中发生僵死,即程序不再能够正确执行,因为它无法访问到足够的Java对象的内存。以下是一些可能导致JVM内存不足的原因以及相应的解决方案:

      1. Java堆不足:
      2. 在大型项目中,如果Java堆(JVM的堆内存)不足,Java对象的内存分配和垃圾回收可能会出现性能瓶颈,导致应用在执行过程中阻塞或无法正常运行。
      3. 可以尝试以下方法解决:增加Java堆的大小,或者调整Java的垃圾回收策略,例如通过增加垃圾回收的粒度或减少回收频率来避免过多的垃圾回收。
      4. 例如,你可以通过以下代码片段在Java 8中设置堆大小为1024MB: java Configuration configuration = new Configuration(); configuration.set(JvmOptions.JVM_HEAP_SIZE, 1024 * 1024 * 1024);
      5. 或者在Android Studio中,可以打开jvmOptions标签页,点击Heap Size标签,设置堆大小为1024MB。
      6. 对于大型项目,你可能需要使用JVM工具(如JProfiler或VisualVM)来跟踪Java堆的使用情况,并手动调整堆大小以达到最佳性能。

      7. Java对象大小过大:

      8. Java对象的大小过大,超过Java堆的可用内存,会导致内存溢出。此时,JVM可能会选择将对象分配到内存之外的虚拟机栈(栈内存)中,从而导致应用僵死。
      9. 解决方法:在Java对象创建或初始化时,尽量减少对象的大小,避免创建过多的超大规模对象。例如,如果一个对象有100个成员变量和20个方法,可以将其合并成一个大对象,这样可以减少对象的大小,从而避免内存溢出。
      10. 例如,以下代码片段在Java 8中创建一个大对象并初始化它: java Object object = new Object(); for (int i = 0; i < 100; i++) { object.put(i, i); }
      11. 在Android Studio中,你可以在application类中创建一个大对象并初始化它,例如: ```java // 在Java 8中创建一个大对象并初始化它 class Application { private int[] array = new int[100]; // 初始化大对象的成员变量 public void init(int[] array) { this.array = array; } }

        // 在Android Studio中创建一个大对象并初始化它 Application application = new Application(); application.init(new int[100]); ```

      12. Java代码执行时间过长:

      13. 如果Java代码执行时间过长,导致内存频繁被释放,也会导致Java对象的内存不足。
      14. 解决方法:优化Java代码,减少不必要的对象创建和垃圾回收,同时提高Java程序的执行效率。例如,使用多线程或并行处理可以减少对单个线程的处理压力,从而减少内存消耗。
      15. 例如,以下代码片段在Java 8中使用多线程并行执行一些耗时操作: ```java public class Main { public static void main(String[] args) { // 在Java 8中使用多线程并行执行一些耗时操作 ExecutorService executorService = Executors.newFixedThreadPool(10); int[] array = new int[100]; for (int i = 0; i < 100; i++) { executorService.submit(() -> { System.out.println(i); }); }

             executorService.shutdown();
             try {
                 executorService.awaitTermination(5, TimeUnit.SECONDS);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
        
             for (int i = 0; i < 100; i++) {
                 System.out.println(array[i]);
             }
         }
        

        } ```

      16. Java反射管理不当:

      17. Java反射(Reflection)允许开发者动态地访问和修改Java类的属性和方法,这可能会导致一些运行时错误,如内存泄漏。
      18. 解决方法:在Java反射中,尽量避免对类的静态成员变量、实例变量或方法进行直接操作,因为这可能导致内存泄漏。在使用反射进行对象属性或方法的修改时,应该在对象的实例上进行,或者通过工具(如Gradle或Maven)自动处理类的加载和初始化。
      19. 例如,以下代码片段在Java 8中通过反射修改对象的属性: java // 在Java 8中通过反射修改对象的属性 Field field = MyClass.class.getDeclaredField("myField"); field.setAccessible(true); field.set(myObject, 100);

      总之,当JVM内存不足导致应用僵死时,需要找到并解决问题的根源。通过增加Java堆大小、调整垃圾回收策略、优化Java代码、并行处理耗时操作、正确处理反射等方法,可以有效地解决JVM内存不足的问题,确保Java程序的正常运行。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部