JVM学习——1

定义

Java Virtual Machine -java程序的运行环境
好处:

  • 一次编写,到处运行
  • 自动内存管理,垃圾回收功能
  • 数组下标越界 越界检查
  • 多态
    比较:
    jvm jre jdk
    在这里插入图片描述
    构成:

在这里插入图片描述

1.程序计数器

定义

Program counter register程序计数器(寄存器)
在这里插入图片描述
jvm中的组件解释器将虚拟机指令翻译成机器码,提供给cpu执行

  • 作用:记住下一条jvm指令
  • 特点
    1. 线程私有
    2. 不会存在内存溢出

2.栈

Java Virtual Machine Stacks(Java虚拟机栈)

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

垃圾回收不涉及栈内存回收
方法内的局部变量是否线程安全

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

-Xss 设置线程栈空间

栈内存溢出

  • 栈帧过导致栈内存溢出
  • 栈帧过多导致内存溢出

运行诊断

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

3.堆

Heap堆,通过new关键字,创建对象都会使用堆内存

特点

  • 线程共享,堆中对象都需要考虑线程安全的问题
  • 有垃圾回收机制

内存诊断

  1. jps工具 查看当前系统中有那些java进程
  2. jmap工具: 查看堆内存占用情况
  3. jconsole工具 图形界面的,多功能的检测工具,可以连续监测
  4. jvisualvm 可视化虚拟机

4.方法区

在这里插入图片描述

5.运行时常量池

对于class文件 javap -v HelloWord.class 反编译class文件
类基本信息,常量池,类方法定义,包含了虚拟机指令

  • 常量池:就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
  • 运行时常量池:常量池是*.class文件中的,当该类被加载,它的常量池信息就会被放入运行时常量池(运行时放入内存中),把里面的符号地址变为真实地址

StringTable串池 hashTable结构 不能扩容
1.常量池中的信息,都回被加载到运行时常量池,这是a b ab都是常量池中的符号,还没有变为java字符串对象
2.ldc #2回把 a符号变为“a"字符串对象(先去stringTable中找,没找到则放入string table
在这里插入图片描述

打印false,true,s3在串池中而s4在堆中,s5编译期间结果已确认,直接记录为ab,发现串池中有了
在这里插入图片描述
打印结果true,true,因为一开始串池中没有,所以直接将s放入了串池,所有s==”ab“
若第一行直接有一个String x = ”ab“,在后面有这个s则串池中已经有了不会放入,则s != “ab”

5.1 StringTable特性

  • 常量池中的字符串仅是符号,第一次用到时才变为对象
  • 利用串池的机制,来避免重复创建字符串对象
  • 字符串变量拼接的原理时StringBuilder(1.8)
  • 字符串变量拼接的原理时编译器优化
  • 可以使用intern方法,主动将串池中还没有的字符串对象放入串池
  • 1.8将这个字符串对象尝试放入串池,如果有则并不会放入,没有则放入并将串池中的对象返回
  • 1.6将这个字符串对象尝试放入串池,如果有则并不会放入,没有则复制一份放入并将串池中的对象返回 此时池两个对象

5.2 StringTable性能调优

调整:-XX:StringTableSize=桶个数 适当调大减少哈希碰撞提升性能
大量字符串时可以先inter()

6 直接内存

Direct mEMORY

  • 常用于NIO操作,用于数据缓冲区
  • 分配回收成本较高,但读写性能高
  • 不受JVM内存回收管理
    ByteBuffer.allocateDirect();
  • 使用了Unsafe对象完成直接内存的分配回收,并且回收需要主动调用freeMemory方法
  • ByteBuffer的实现类内部,使用了Cleaner(虚引用)来检测ByteBuffer对象,一旦ByteBuffer对象被垃圾回收,那么就会由ReferenceHandler线程通过Cleaner的clean方法调用freeMemory来释放直接内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值