黑马Java虚拟机 JVM(二)

本文详细介绍了Java内存的各个区域,包括线程运行诊断、本地方法栈、堆内存、方法区、堆内存溢出的诊断与处理,以及StringTable的特性。同时,讲解了如何使用jps、jmap和jconsole等工具进行内存诊断,并探讨了方法区内存溢出和运行时常量池的相关问题。此外,还阐述了StringTable在1.6和1.8版本中的不同行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 线程运行诊断

CPU占用过多
定位:

  • 用top定位哪个进程对cpu占用过高
  • ps H -eo pid, tid, %cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)
  • jstack进程id:可以根据线程id找到有问题的线程,进一步定位到问题代码的源码行号
2. 本地方法栈

在这里插入图片描述

  • Native Method Stacks:本地方法栈
  • 解释:本地方法就是那些不是由Java代码编写的方法,因为Java代码有限制,有些情况下不能和操作系统底层进行交互,所以就需要由C 或 C++ 编写的本地方法来与操作系统打交道,所以本地方法执行时候所使用的就是本地方法栈
  • 作用:为本地方法的运行提供内存空间
3. 堆(Heap)
  • 通过new关键字,创建对象都会使用堆内存
  • 特点:
    • 它是线程共享的,堆中对象都需要考虑线程安全的问题
    • 有垃圾回收机制
4. 堆内存溢出
  • OutOfMemoryError:Java heap space
  • 不断产生对象,且对象被使用(不会被回收),对象堆积会造成堆内存溢出
5. 堆内存诊断
  • jps工具
    • 查看当前系统中有哪些Java进程
  • jmap工具
    • 查看堆内存占用情况 jmap -heap 进程id(查询当前时刻,不能连续监测)
  • jconsole工具
    • 图形界面,多动能的监测工具,可以连续监测
6. 方法区(Method Area)
  • 所有Java虚拟机线程共享的区域
  • 存储了和类相关的信息
  • 方法区在虚拟机启动时被创建
7. 方法区内存溢出
  • 1.8之前会导致永久代内存溢出
 java.lang.OutOfMemoryError:PermGen space
 - XX:MaxPermSize=8m
  • 1.8之后会导致元空间内存溢
    | | |
    |–|--|
    | | |
演示元空间内存溢出 java.lang.OutOfMemoryError:Metaspace
- XX:MaxMetaspaceSize=8m
8. 运行时常量池
  • 常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量(字符串、基本整数、布尔类型等)等信息
  • 运行时常量池,常量池是*.class文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址
9. StringTable特性
  • 常量池中的字符串仅是符号,第一次用到时才变为对象
  • 利用串池的机制,来避免重复创建字符串对象
  • 字符串变量拼接的原理是StringBuilder(1.8)
  • 字符串常量拼接的原理是编译器优化
  • 可以使用intern方法,主动将串池中还没有的字符串对象放入串池
    • 1.8将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池,会把串池中的对象返回
    • 1.6将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池,会把串池中的对象返回
10. StringTable位置

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SimpleZihao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值