JVM学习笔记内存结构-创新互联
作用:记录下一条JVM指令的执行地址
特点:
- 线程私有
- 不存在内存溢出
- 每个线程运行时所需的内存称为虚拟机栈。
- 每个栈由多个栈帧(Frame)组成,每个栈帧对应每次方法调用时占用的内存。
- 每个线程只能有一个活动栈帧,对应当前正在执行的方法。
问题辨析:
- 垃圾回收会管理栈内存吗?不会,栈产生的栈帧内存每次调用完成后都会弹出栈,会被自动回收。
- 栈内存分配越大越好?不,栈内存大了,线程数会减少。
- 方法内局部变量是否线程安全?
- 如果变量作用范围只是在方法内,则线程安全。
- 若变量引用了对象,则需要考虑线程安全
栈内存溢出
- 栈帧过多导致栈内存溢出
- 栈帧过大导致栈内存溢出
案例1:CPU占用过多
定位
- 用top定位哪个进程对CPU的占用过高
ps H -eo pid,tid,%cpu | grep 进程id
(线程id为10进制)jstack 进程id
(线程id为16进制)- 通过线程
id
进一步定位到代码的源码行号
- 通过线程
案例2:程序运行较长时间无结果
用jstack
命令定位查看是否发生死锁
用native修饰
堆通过new
创建的对象都会使用堆内存
特点
- 线程共享,需要考虑线程安全问题
- 有垃圾回收机制
堆内存溢出
将堆内存设置小些,以方便排查堆内存溢出问题
堆内存诊断
工具
- jps
- jmap
- jconsole
PS C:\Users\28599\Desktop\JVM\代码\jvm\jvm>jmap -heap 8284
Attaching to process ID 8284, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.331-b09
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 4250927104 (4054.0MB)
NewSize = 88604672 (84.5MB)
MaxNewSize = 1416626176 (1351.0MB)
OldSize = 177733632 (169.5MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 66584576 (63.5MB)
used = 1331712 (1.27001953125MB)
free = 65252864 (62.22998046875MB)
2.0000307578740157% used
From Space:
capacity = 11010048 (10.5MB)
used = 0 (0.0MB)
free = 11010048 (10.5MB)
0.0% used
To Space:
capacity = 11010048 (10.5MB)
used = 0 (0.0MB)
free = 11010048 (10.5MB)
0.0% used
PS Old Generation
capacity = 177733632 (169.5MB)
used = 1052296 (1.0035476684570312MB)
free = 176681336 (168.49645233154297MB)
0.5920635212135877% used
3162 interned Strings occupying 280536 bytes.
jvisualvm
执行堆dump
查找大的对象
方法区存储每个类的结构,如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括类和实例初始化和接口初始化中使用的特殊方法。
JDK7 之前(永久代)用于存储已被虚拟机加载的类信息、常量、字符串常量、类静态变量、即时编译器编译后的代码等数据。每当一个类初次被加载的时候,它的元数据都会被放到永久代中。永久代大小有 限制,如果加载的类太多,很可能导致永久代内存溢出,即 java.lang.OutOfMemoryError: PermGen。
JDK8 彻底将永久代移除出 HotSpot JVM,将其原有的数据迁移至 Java Heap 或 Native Heap(Metaspace),取代它的是另一个内存区域被称为元空间(Metaspace)。
元空间(Metaspace):元空间是方法区的在 HotSpot JVM 中的实现,方法区主要用于存储类信息、常 量池、方法数据、方法代码、符号引用等。元空间的本质和永久代类似,都是对 JVM 规范中方法区的实 现。不过元空间与永久代之间大的区别在于:元空间并不在虚拟机中,而是使用本地内存。 可以通过 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 配置内存大小。
常量池javap -v .\HelloWorld.class
Classfile /C:/Users/28599/Desktop/JVM/代码/jvm/jvm/out/production/jvm/cn/itcast/jvm/t5/HelloWorld.class
Last modified 2023-1-3; size 567 bytes
MD5 checksum 8efebdac91aa496515fa1c161184e354
Compiled from "HelloWorld.java"
public class cn.itcast.jvm.t5.HelloWorld
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #6.#20 // java/lang/Object."":()V
#2 = Fieldref #21.#22 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #23 // hello world
#4 = Methodref #24.#25 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #26 // cn/itcast/jvm/t5/HelloWorld
#6 = Class #27 // java/lang/Object
#7 = Utf8 #8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcn/itcast/jvm/t5/HelloWorld;
#14 = Utf8 main
#15 = Utf8 ([Ljava/lang/String;)V
#16 = Utf8 args
#17 = Utf8 [Ljava/lang/String;
#18 = Utf8 SourceFile
#19 = Utf8 HelloWorld.java
#20 = NameAndType #7:#8 // "":()V
#21 = Class #28 // java/lang/System
#22 = NameAndType #29:#30 // out:Ljava/io/PrintStream;
#23 = Utf8 hello world
#24 = Class #31 // java/io/PrintStream
#25 = NameAndType #32:#33 // println:(Ljava/lang/String;)V
#26 = Utf8 cn/itcast/jvm/t5/HelloWorld
#27 = Utf8 java/lang/Object
#28 = Utf8 java/lang/System
#29 = Utf8 out
#30 = Utf8 Ljava/io/PrintStream;
#31 = Utf8 java/io/PrintStream
#32 = Utf8 println
#33 = Utf8 (Ljava/lang/String;)V
{public cn.itcast.jvm.t5.HelloWorld();
descriptor: ()V
flags: ACC_PUBLIC
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String hello world
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 6: 0
line 7: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
}
SourceFile: "HelloWorld.java"
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站栏目:JVM学习笔记内存结构-创新互联
分享地址:http://hbruida.cn/article/dehiie.html