java中jvm

一:介绍

  • 什么是JVM
    定义:java virtual meachine -java运行时环境(java二进制字节码的运行环境)。
  • 好处:
    一次编写到处运行
    自动内存管理,垃圾回收
    数组下标越界检查
    多态
    在这里插入图片描述
    java虚拟机:

java的内存结构包括:

  • 程序计数器
  • 虚拟机栈
  • 本地方法栈
  • 方法区

1.1 程序计数器

在这里插入图片描述

  • java代码在执行的过程:首先被编译成二进制字节码(jvm指令),然后通过解释器生成为机器码,最后才会被CPU执行。
  • 而解释器在执行每一条字节码指令时,需要程序计数器来指定需要执行的指令。此时程序计数器中存储的是jvm下一个执行的地址
  • 正是因为能编辑为机器码,jvm才有一次编辑,多平台使用。因为无论linux和windows系统,都会执行机器码

特点:

  • 线程私有
  • 不会出现内存泄漏

1.2 栈

1.2.1栈的定义

定义:

  • 每个线程运行时所需要的内存,称为虚拟机栈
  • 每个栈由多个栈帧组成,对应着每次方法调用时所占用的内存
  • 每个线程只能有一个活动栈帧(正在执行的方法),对应着当前正在执行的那个方法
  • 特点:先进后出

一个线程需要一个栈;一个栈帧对应一个方法的调用;
栈和栈帧的关系:线程执行方法的时候,会调用方法,会将栈栈放入栈内,当方法执行完后,会将栈帧释放掉
在这里插入图片描述
问题解析:
1:垃圾回收是否涉及栈内存
不涉及,方法执行完后,对应的栈帧就会被出栈,被释放掉,不涉及垃圾回收
2:栈内存分配越大越好吗?
不是:物理内存大小是一定的,当栈内存大时,线程数就会少。
3:方法内的局部变量是否线程安全?

  • 如果方法内局部变量没有逃离方法的作用访问,是线程安全的
  • 如果是局部变量引用了对象,并逃离方法的作用方法,需要考虑线程安全

查看线程是否安全:看这个变量对多个线程是共享的,还是私有的

public class Demo{
   static void hello(){
       int x=0;
       for (int i=0;i<100;i++){
       x++;
       }
System.out.println(x);

}
}

此时线程安全
在这里插入图片描述
此时局部变量是线程不安全的

public class Demo{
   static void hello(){
       static int x=0;
       for (int i=0;i<100;i++){
       x++;
       }
System.out.println(x);

}
}

在这里插入图片描述
在这里插入图片描述

1.2.2 栈内存溢出

STACKOVERFLOWERROE
什么情况会导致内存溢出

  • 栈帧多时,一直有栈帧进栈;当递归次数多时
  • 栈帧过大导致内存溢出,

1.2.3 线程运行诊断

  • 案例一:cpu占用过多
    定位

    • 用top定位哪个线程对cpu占用过高
    • ps -H pid,tid,%cpu | grep 进程id,(用ps命令进一步定位那个线程引起的cpu占用过高)
    • jstack 进程id
      • 可以根据线程id,找到问题的线程,进一步定位到出现问题的代码
  • 案例二:一段程序,运行好长时间,没有等到返回的结果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章