java虚拟机实例 有木有关于Java虚拟机的书籍推荐?感激不尽?

[更新]
·
·
分类:互联网
2041 阅读

java虚拟机实例

有木有关于Java虚拟机的书籍推荐?感激不尽?

有木有关于Java虚拟机的书籍推荐?感激不尽?

一、Java从入门到精通《Java从入门到精通(第3版)》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Java语言进行程序开发需要掌握的知识。《Java从入门到精通(第3版)》编辑推荐:“软件开发视频大讲堂”丛书系清华社“视频大讲堂”重点大系之一。该大系包括多个子系列,每个子系列的图书在其同品种的图书中销售名列前茅,
二、Java核心技术(卷1):基础知识Java领域最有影响力和价值的著作之一,与《Java编程思想》齐名,10余年全球畅销不衰,广受好评;2)根据Java SE 7全面更新,系统全面讲解Java语言的核心概念、语法、重要特性和开发方法,包含大量案例,实践性强
三、Java编程思想《Java编程思想(第4版)》书共22章,包括操作符、控制执行流程、访问权限控制、复用类、多态、接口、通过异常处理错误、字符串、泛型、数组、容器深入研究、Iava’UO系统、枚举类型、并发以及图形化用户界面等内容。这些丰富的内容,包含了Java语言基础语法以及高级特性,适合各个层次的Java程序员阅读,同时也是高等院校讲授面向对象程序设计语言以及Java语言的绝佳教材和参考书。
四、深入理解Java虚拟机:JVM高级特性与最佳实践第1版两年内印刷近10次,4家网上书店的评论近4?000条,98%以上的评论全部为5星级的好评,是整个Java图书领域公认的经典著作和超级畅销书,繁体版在台湾也十分受欢迎。第2版在第1版的基础上做了很大的改进:根据最新的JDK 1.7对全书内容进行了全面的升级和补充;增加了大量处理各种常见JVM问题的技巧和最佳实践;增加了若干与生产环境相结合的实战案例;对第1版中的错误和不足之处的修正;等等。第2版不仅技术更新、内容更丰富,而且实战性更强。五、Sun 公司核心技术丛书:Effective Java中文版在Java编程中78条极具实用价值的经验规则,这些经验规则涵盖了大多数开发人员每天所面临的问题的解决方案。通过对Java平台设计专家所使用的技术的全面描述,揭示了应该做什么,不应该做什么才能产生清晰、健壮和高效的代码。第2版反映了Java 5中最重要的变化,并删去了过时的内容。
六、图灵程序设计丛书:Java程序员修炼之道《Java程序员修炼之道》分为四部分,第一部分全面介绍Java 7的新特性,第二部分探讨Java关键编程知识和技术,第三部分讨论JVM上的新语言和多语言编程,第四部分将平台和多语言编程知识付诸实践。从介绍Java 7的新特性入手,《Java程序员修炼之道》涵盖了Java开发中最重要的技术,比如依赖注入、测试驱动的开发和持续集成,探索了JVM上的非Java语言,并详细讲解了多语言项目, 特别是涉及Groovy、Scala和Clojure语言的项目。此外,书中含有大量代码示例,帮助读者从实践中理解Java语言和平台。
七、Head First Java(中文版)《Head First Java》(中文版)(第2版)是本完整的面向对象(object-oriented,OO)程序设计和Java的学习指导。此书是根据学习理论所设计的,让你可以从学习程序语言的基础开始一直到包括线程、网络与分布式程序等项目。最重要的,你会学会如何像个面向对象开发者一样去思考。
八、Java 7入门经典《Java 7入门经典》是关于Java语言讲解最为细致、全面的入门书籍,介绍了使用最新的Java JDK 7开发程序所需要的所有基础知识。书中包含大量的示例,清晰地解释了涉及的关键概念,演示了Java开发的复杂细节。

如何正确学会Java虚拟机调优?

一点小经验仅供参考:
1) 堆
运行时数据区域,所有类实例和数组的内存均从此处分配。Java 虚拟机启动时创建。对象的堆内存由称为垃圾回收器 的自动内存管理系统回收。
堆由两部分组成:
其中eden fromspace tospace也叫年轻代(young),old space叫旧生代.
其中还有S1,S0(在JDK的自带工具输出中会看到),分别指的是Survivor space,存放每次垃圾回收后存活的对象.
Old Generation , 主要存放应用程序中生命周期长的存活对象
垃圾回收主要是对Young Generation块和Old Generation块内存进行回收,YG用来放新产生的对象,经过几次回收还没回收掉的对象往OG中移动,
对YG进行垃圾回收又叫做MinorGC,对OG垃圾回收叫MajorGC,两块内存回收互不干涉
2) 非堆内存
JVM具有一个由所有线程共享的方法区。方法区属于非堆内存。它存储每个类结构,如运行时常数池、字段和方法数据,以及方法和构造方法的代码。它是在 Java 虚拟机启动时创建的。
除了方法区外,Java 虚拟机实现可能需要用于内部处理或优化的内存,这种内存也是非堆内存。 例如,JIT 编译器需要内存来存储从 Java 虚拟机代码转换而来的本机代码,从而获得高性能。
Permanent Generation (图中的Permanent Space) 存放JVM自己的反射对象,比如类对象和方法对象
3) 回收算法和过程
JVM采用一种分代回收 (generational collection) 的策略,用较高的频率对年轻的对象(young generation)进行扫描和回收,这种叫做minor collection,而对老对象(old generation)的检查回收频率要低很多,称为major collection。这样就不需要每次GC都将内存中所有对象都检查一遍。
当一个URL被访问时,内存申请过程 如下:
A. JVM会试图为相关Java对象在Eden中初始化一块内存区域
B. 当Eden空间足够时,内存申请结束。否则到下一步
C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收), 释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区
D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区
E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)
F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”
对象衰老的过程
young generation的内存,由一块Eden(伊甸园,有意思)和两块Survivor Space(1.4文档中称为semi-space)构成。新创建的对象的内存都分配自eden。两块Survivor Space总有会一块是空闲的,用作copying collection的目标空间。Minor collection的过程就是将eden和在用survivor space中的活对象copy到空闲survivor space中。所谓survivor,也就是大部分对象在伊甸园出生后,根本活不过一次GC。对象在young generation里经历了一定次数的minor collection后,年纪大了,就会被移到old generation中,称为tenuring。(是否仅当survivor space不足的时候才会将老对象tenuring? 目前资料中没有找到描述)
剩余内存空间不足会触发GC,如eden空间不够了就要进行minor collection,old generation空间不够要进行major collection,permanent generation空间不足会引发full GC。
4 接下来这部分讲解的是TOMCAT或者其他服务器出现如下错误时的分析:
1、首先是: Java heap space
解释:
Heap size 设置
JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。
提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
解决方法:
手动设置Heap size
修改TOMCAT_,在“echo Using CATALINA_BASE: $CATALINA_BASE”上面加入以下行:
Java代码
set JAVA_OPTS%JAVA_OPTS% -server -Xms800m -Xmx800m -XX:MaxNewSize256m
set JAVA_OPTS%JAVA_OPTS% -server -Xms800m -Xmx800m -XX:MaxNewSize256m
或修改
在“echo Using CATALINA_BASE: $CATALINA_BASE”上面加入以下行:
JAVA_OPTS$JAVA_OPTS -server -Xms800m -Xmx800m -XX:MaxNewSize256m
2、其次是: PermGen space
原因:
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
解决方法:
1. 手动设置MaxPermSize大小
修改TOMCAT_(Linux下为),在Java代码
“echo Using CATALINA_BASE: $CATALINA_BASE”上面加入以下行:
set JAVA_OPTS%JAVA_OPTS% -server -XX:PermSize128M -XX:MaxPermSize512m
“echo Using CATALINA_BASE: $CATALINA_BASE”上面加入以下行:
set JAVA_OPTS%JAVA_OPTS% -server -XX:PermSize128M -XX:MaxPermSize512m
下为:
Java代码
JAVA_OPTS$JAVA_OPTS -server -XX:PermSize128M -XX:MaxPermSize512m
JAVA_OPTS$JAVA_OPTS -server -XX:PermSize128M -XX:MaxPermSize512m
JVM的默认设置
堆 (heap)(News Generation 和Old Generaion 之和)的设置
初始分配的内存由-Xms指定,默认是物理内存的1/64但小于1G。
最大分配的内存由-Xmx指定,默认是物理内存的1/4但小于1G。
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制,可以由-XX:MinHeapFreeRatio指定。
默认空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制,可以由-XX:MaxHeapFreeRatio指定。
服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小,所以上面的两个参数没啥用。
-Xmn 设置young generation的heap大小
-XX:MinHeapFreeRatio与-XX:MaxHeapFreeRatio设定空闲内存占总内存的比例范围,这两个参数会影响GC的频率和单次GC的耗时。-XX:NewRatio决定young与old generation的比例。Young generation空间越大,minor collection频率越低,但是old generation空间小了,又可能导致major collection频率增加。-XX:NewSize和-XX:MaxNewSize直接指定了young generation的缺省大小和最大大小。
非堆内存 的设置
默认分配为64M
-XX:PermSize设置最小分配空间,-XX:MaxPermSize设置最大分配空间。一般把这两个数值设为相同,以减少申请内存空间的时间。
再讲解和笔记下,JDK下的一些相关看内存管理工具的使用:
查看jvm内存状态:
jstat -gcutil pid 1000 20
异常情况的例子
jstat -gcutil pid 1000 20
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 99.99 82.51 53.11 2409 1.205 10117 7250.393 7251.598
0.00 0.00 83.42 82.55 53.10 2409 1.205 10118 7252.650 7253.855
0.00 0.00 56.06 82.46 53.10 2410 1.205 10120 7254.467 7255.672
0.00 0.00 32.11 82.55 53.10 2411 1.205 10121 7256.673 7257.877
0.00 0.00 99.99 82.55 53.10 2412 1.205 10123 7257.026 7258.231
0.00 0.00 76.00 82.50 53.10 2412 1.205 10124 7259.241 7260.446
这个数据显示Full GC频繁发生。
正常情况的例子
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
参数含义:
S0:Heap上的 Survivor space 0 段已使用空间的百分比
S1:Heap上的 Survivor space 1 段已使用空间的百分比
E: Heap上的 Eden space 段已使用空间的百分比
O: Heap上的 Old space 段已使用空间的百分比
P: Perm space 已使用空间的百分比
YGC:从程序启动到采样时发生Young GC的次数
YGCT:Young GC所用的时间(单位秒)
FGC:从程序启动到采样时发生Full GC的次数
FGCT:Full GC所用的时间(单位秒)
GCT:用于垃圾回收的总时间(单位秒)
2 Dump出内存
2.1 找出要dump的线程pid
在Linux下,使用ps –aux
2.2 Dump出内存使用详情
可以通过命令:
jmap -dump:filea.hprof pid
例如:jmap -heap 2343,可以看到
Attaching to process ID 2343, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 11.0-b16
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio 40
MaxHeapFreeRatio 70
MaxHeapSize 4294967296 (4096.0MB)
NewSize 2686976 (2.5625MB)
MaxNewSize -65536 (-0.0625MB)
OldSize 5439488 (5.1875MB)
NewRatio 2 (YG,OG 大小比为1:2)
SurvivorRatio 8
PermSize 21757952 (20.75MB)
MaxPermSize 268435456 (256.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity 1260060672 (1201.6875MB)
used 64868288 (61.86322021484375MB)
free 1195192384 (1139.8242797851562MB)
5.148028935546367% used
From Space:
capacity 85524480 (81.5625MB)
used 59457648 (56.70323181152344MB)
free 26066832 (24.859268188476562MB)
69.52120375359195% used
To Space:
capacity 85852160 (81.875MB)
used 0 (0.0MB)
free 85852160 (81.875MB)
0.0% used
~~~~~~~~~~~~~~~~~~~~~~~~~~这三块为上面所说的YG大小和使用情况
PS Old Generation
capacity 2291138560 (2185.0MB)
used 1747845928 (1666.8757705688477MB)
free 543292632 (518.1242294311523MB)
76.28722062099989% used
~~~~~~~~~~~~~~~~~~~~~~~~~~OG大小和使用情况
PS Perm Generation
capacity 108265472 (103.25MB)
used 107650712 (102.6637191772461MB)
free 614760 (0.5862808227539062MB)
99.43217353728436% used
jstat
jstat是vm的状态监控工具,监控的内容有类加载、运行时编译及GC。
使用时,需加上查看进程的进程id,和所选参数。以下详细介绍各个参数的意义。
jstat -class pid:显示加载class的数量,及所占空间等信息。
jstat -compiler pid:显示VM实时编译的数量等信息。
jstat -gc pid:可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。
jstat -gccapacity:可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。其他的可以根据这个类推, OC是old内纯的占用量。
jstat -gcnew pid:new对象的信息。
jstat -gcnewcapacity pid:new对象的信息及其占用量。
jstat -gcold pid:old对象的信息。
jstat -gcoldcapacity pid:old对象的信息及其占用量。
jstat -gcpermcapacity pid: perm对象的信息及其占用量。
jstat -util pid:统计gc信息统计。
jstat -printcompilation pid:当前VM执行的信息。
除了以上一个参数外,还可以同时加上 两个数字,如:jstat -printcompilation 3024 250 6是每250毫秒打印一次,一共打印6次,还可以加上-h3每三行显示一下标题。
例子:
jstat -gcutil pid 1000 20
S0 S1 E O P YGC YGCT FGC FGCT GCT
47.49 0.00 64.82 46.08 47.69 20822 2058.631 68 22.734 2081.365
0.00 37.91 38.57 46.13 47.69 20823 2058.691 68 22.734 2081.425 这里发生了一次YG GC,也就是MinorGC,耗时0.06s
46.69 0.00 15.19 46.18 47.69 20824 2058.776 68 22.734 2081.510
46.69 0.00 74.59 46.18 47.69 20824 2058.776 68 22.734 2081.510
0.00 40.29 19.95 46.24 47.69 20825 2058.848 68 22.734 2081.582
MajorGC平均时间:22.734/680.334秒
MinorGC平均时间:2058.691/208230.099秒