JVM 原理

1、栈上分配、逃逸分析

2、四种引用

软引用:一个对象只持有软引用,那么当堆空间不足时,就会被回收

弱引用:在系统 GC 时,只要发现弱引用,不管系统堆空间使用情况如何,都会将对象进行回收。但是,由于垃圾回收器的线程通常优先级很低,因此,并不一定能很快地发现持有弱引用的对象。在这种情况下,弱引用对象可以存在较长的时间。

软引用 、弱引用 都非常适合来保存那些可有可无的缓存数据。 如果这么做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出 。 而当内存资源充足时,这些缓存数据又可以存在相当长的时间,从而起到加速系统的作用 。

虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程

为什么需要 TLAB 这个区域呢?这是为了加速对象分配而生的 。 由于对象一般会分配在堆上,而堆是全局共享的 。 因此在同一时间,可能会有多个线程在堆上申请空间 。 因此,每一次对象分配都必须要进行同步,而在竞争激烈的场合分配的效率又会进一步下降。

Linux 下的性能监控工具
显示系统整体资源使用情况一一top 命令

V i s u a l VM 也支持远程川X 连接
Thread Dump 和分析
内存快照分析
Arthas
fastthread.io https://developer.aliyun.com/article/1149635

JVM 参数

官网全量参数文档:https://docs.oracle.com/en/java/javase/14/docs/specs/man/java.html

Thread.currentThread().interrupt()

对线面试官系列

该播主除了一些不错的文章,推荐关注。
为什么需要Java内存模型?
Java从编译到执行,发生了什么?
双亲委派机制
深入浅出 Java 内存模型
JVM内存结构
垃圾回收机制
CMS垃圾回收器
G1垃圾收集器
JVM调优

heapdump 系列

JVM虚拟机 这个博主整理了不少好文章

JVM性能调优监控工具专题一:JVM自带性能调优工具(jps,jstack,jmap,jhat,jstat,hprof)

jps [options] [hostid]

使用jps查看出当前有哪些Java进程,获取该Java进程的id

-q 不输出类名、Jar名和传入main方法的参数
-m 输出传入main方法的参数
-l 输出main类或Jar的全限名
-v 输出传入JVM的参数

jstack

jstack主要用来查看某个Java进程内的线程堆栈信息。

jstack [option] pid
jstack [option] executable core
jstack [option] [server-id@]remote-hostname-or-ip

命令行参数选项说明如下:

-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)

jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。

jmap(Memory Map)和 jhat(Java Heap Analysis Tool):

jmap导出堆内存,然后使用jhat来进行分析
jmap用来查看堆内存使用状况,一般结合jhat使用。

jmap [option] pid
jmap [option] executable core
jmap [option] [server-id@]remote-hostname-or-ip

  • 打印进程的类加载器和类加载器加载的持久代对象信息: jmap -permstat pid
  • 查看进程堆内存使用情况:包括使用的GC算法、堆配置参数和各代中堆内存使用:jmap -heap pid
  • 查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象:jmap -histo[:live] pid
  • 用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。需要注意的是 dump出来的文件还可以用MAT、VisualVM等工具查看。
    jmap -dump:format=b,file=dumpFileName pid
    jmap -dump:format=b,file=/home/dump.dat
    jhat -port 8888 /home/dump.dat

jstat(JVM统计监测工具): 看看各个区内存和GC的情况

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

vmid是Java虚拟机ID,在Linux/Unix系统上一般就是进程ID。
interval是采样时间间隔。
count是采样数目。
比如下面输出的是GC信息,采样时间间隔为250ms,采样数为6
jstat -gc 2860 250 6
在这里插入图片描述
要明白上面各列的意义,先看JVM堆内存布局
在这里插入图片描述
可以看出:

堆内存 = 年轻代 + 年老代 + 永久代
年轻代 = Eden区 + 两个Survivor区(From和To)

现在来解释各列含义:

S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
EC、EU:Eden区容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用量
YGC、YGT:年轻代GC次数和GC耗时
FGC、FGCT:Full GC次数和Full GC耗时
GCT:GC总耗时

hprof(Heap/CPU Profiling Tool): hprof能够展现CPU使用率,统计堆内存使用情况。

HPROF: 一个Heap/CPU Profiling工具:J2SE中提供了一个简单的命令行工具来对java程序的cpu和heap进行 profiling,叫做HPROF。HPROF实际上是JVM中的一个native的库,它会在JVM启动的时候通过命令行参数来动态加载,并成为 JVM进程的一部分。若要在java进程启动的时候使用HPROF,用户可以通过各种命令行参数类型来使用HPROF对java进程的heap或者 (和)cpu进行profiling的功能。HPROF产生的profiling数据可以是二进制的,也可以是文本格式的。这些日志可以用来跟踪和分析 java进程的性能问题和瓶颈,解决内存使用上不优的地方或者程序实现上的不优之处。二进制格式的日志还可以被JVM中的HAT工具来进行浏览和分析,用 以观察java进程的heap中各种类型和数据的情况。在J2SE 5.0以后的版本中,HPROF已经被并入到一个叫做Java Virtual Machine Tool Interface(JVM TI)中。

java -agentlib:hprof[=options] ToBeProfiledClass
java -Xrunprof[:options] ToBeProfiledClass
javac -J-agentlib:hprof[=options] ToBeProfiledClass

完整的命令选项如下:

Option Name and Value Description Default


heap=dump|sites|all heap profiling all
cpu=samples|times|old CPU usage off
monitor=y|n monitor contention n
format=a|b text(txt) or binary output a
file= write data to file java.hprof[.txt]
net=: send data over a socket off
depth= stack trace depth 4
interval= sample interval in ms 10
cutoff= output cutoff point 0.0001
lineno=y|n line number in traces? y
thread=y|n thread in traces? n
doe=y|n dump on exit? y
msa=y|n Solaris micro state accounting n
force=y|n force output to y
verbose=y|n print messages about dumps y

使用jstack来分析死锁问题

继续使用jstack来分析HashMap在多线程情况下的死锁问题

java内存管理深入浅出

讲述了:

  • Java如何管理内存
  • 内存泄漏以及内存区域的组成
  • 内存中数据是如何存储的(基本数据类型、字符串、类等)
  • 内存管理机制和垃圾回收机制
  • final问题
  • 如何把程序写得更健壮
    • 尽早释放无用对象的引用
    • 定义字符串应该尽量使用String str=”hello”;的形式,避免使用String str = new String(“hello”);的形式
    • 大量使用字符串处理时,避免使用String,应大量使用StringBuffer
    • 尽量少用静态变量,因为静态变量是全局的,GC不会回收的;
    • 尽量避免在类的构造函数里创建、初始化大量的对象,防止在调用其自身类的构造器时造成不必要的内存资源浪费,尤其是大对象,JVM会突然需要大量内存,这时必然会触发GC优化系统内存环境;显示的声明数组空间,而且申请数量还极大。
    • 在合适的场景下使用对象池技术以提高系统性能,缩减缩减开销
    • 大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。
    • 不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。
    • 一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成Out Of Memory Error的状况
    • 尽量少用finalize函数,因为finalize()会加大GC的工作量,而GC相当于耗费系统的计算能力。
    • 不要过滥使用哈希表,有一定开发经验的开发人员经常会使用hash表(hash表在JDK中的一个实现就是HashMap)来缓存一些数据,从而提高系统的运行速度。比如使用HashMap缓存一些物料信息、人员信息等基础资料,这在提高系统速度的同时也加大了系统的内存占用,特别是当缓存的资料比较多的时候。其实我们可以使用操作系统中的缓存的概念来解决这个问题,也就是给被缓存的分配一个一定大小的缓存容器,按照一定的算法淘汰不需要继续缓存的对象,这样一方面会因为进行了对象缓存而提高了系统的运行效率,同时由于缓存容器不是无限制扩大,从而也减少了系统的内存占用。现在有很多开源的缓存实现项目,比如ehcache、oscache等,这些项目都实现了FIFO 、MRU等常见的缓存算法。

JVM性能监控与故障处理

  • BTrace动态日志跟踪
    通过BTrace可以打印调用堆栈、参数、返回值,还可以进行性能监视、定位连接泄漏、内存泄漏、解决多线程竞争问题。
    HotSwap技术:代码热替换技术,HotSpot虚拟机允许在不停止运行的情况下,更新已经加载的类的代码。

推荐资料:
JVM 优化经验总结
JVM 垃圾回收器工作原理及使用实例介绍
JVM详解及优化

Mark Word

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值