JVM
定义:JVM:Java Virtual Machine,也就是Java运行时所需要的环境(Java二进制字节码运行时所需要的环境)
好处:
1.java代码一次编写,跨平台运行
2.自动内存管理,垃圾回收
3.数组下标越界检查
4.多肽
JVM与jdk、jre的关系
JVM内存结构
1.程序计数器
java源代码编译后无法直接在操作系统上运行。
程序计数器的作用就是记录下一条jvm指令的地址,在物理上是基于cpu中的寄存器实现的。
特点:
1.线程私有(每一个线程都有自己的程序计数器)
2.唯一不存在内存溢出的区
2.虚拟机栈
定义:栈:线程运行需要的内存空间。
说明:
1.一个线程有一个虚拟机栈,一个栈内由多个栈帧组成
2.每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法(每个栈帧也需要一块内存来存储方法中的参数、局部变量、返回地址等)
3.从方法调用直至执行完成的过程,对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程(先进后出)
思考:
1.垃圾回收涉及栈内存吗?
答:不涉及。每个线程对应一个虚拟机栈,每个栈帧对应一个方法的调用。每次方法调用结束后,都会被弹出栈,被自动回收,所以不需要垃圾回收来管理栈内存。
垃圾回收只涉及堆内存中的对象,对于栈内存并不涉及。
2.栈内存分配越大越好吗?
答:否。电脑的物理内存是固定的。每个线程对应一个虚拟机栈,当栈分配内存过大时,物理内存中可运行的线程就会变少。
可以通过 -Xss 这个虚拟机参数来指定每个线程的 Java 虚拟机栈内存大小。
3.方法内的局部变量是否线程安全?
答:
情况1:如果方法内局部变量没有逃离方法的作用范围,线程安全。
情况2:如果局部变量引用了对象,并逃离方法作用范围,则需要考虑线程安全的问题。
线程运行诊断
1.cpu占用过高。
linux环境下执行top
命令可以查看所有进程对系统cpu的占用情况。
执行
ps H -eo pid,tid,%cpu
查看进程(pid)、线程(tid)和cpu的占比情况
找到占用cpu高的进程的id,使用
jstack
命令查看进程的具体信息。可以根据线程id(先转换为16进制),找到问题线程,定位到问题代码。