1. 求《JVMG1源码分析和调优豆瓣》全文免费下载百度网盘资源,谢谢~
《JVM G1源码分析和调优豆瓣》网络网盘pdf最新全集下载:
链接: https://pan..com/s/1i8sXLpI7Ey-07u7mGCq2WA
2. jvm源码精析 怎么都是cpp
Attach是什么
在讲这个之前,我们先来点大家都知道的东西,当我们感觉线程一直卡在某个地方,想知道卡在哪里,首先想到的是进行线程mp,而常用的命令是jstack ,我们就可以看到如下线程栈了
2014-06-18 12:56:14
Full thread mp java HotSpot(TM) 64-Bit Server VM (24.51-b03 mixed mode):
"Attach Listener" daemon prio=5 tid=0x00007fb0c6800800 nid=0x440b waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Service Thread" daemon prio=5 tid=0x00007fb0c584d800 nid=0x5303 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=5 tid=0x00007fb0c482e000 nid=0x5103 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=5 tid=0x00007fb0c482c800 nid=0x4f03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=5 tid=0x00007fb0c4815800 nid=0x4d03 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=5 tid=0x00007fb0c4813800 nid=0x3903 in Object.wait() [0x00000001187d2000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007aaa85568> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked <0x00000007aaa85568> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)
"Reference Handler" daemon prio=5 tid=0x00007fb0c4800000 nid=0x3703 in Object.wait() [0x00000001186cf000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007aaa850f0> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked <0x00000007aaa850f0> (a java.lang.ref.Reference$Lock)
3. JVM_字节码文件(ClassFile)详解
我们知道 javac 命令可以将 .java 文件编译成 .class 文件,而这个 Class 文件 中包含了 Java虚拟机 指令集、符号表以及若干其他辅助信息;最终将在 Java虚拟机 运行。
本文是以 JVM8 为例的。
每一个 Class文件 都有如下的 ClassFile 文件结构:
先简单介绍一下 ClassFile 文件结构各部分含义:
描述符是表示字段或方法类型的字符串。
字段描述符表示类、实例或局部变量的类型。
从上面文法可以看出,字段描述符中一共有三个类型:
方法描述符包含 0 个或者多个参数描述符以及一个返回值描述符。
看了描述符,可能大家有点疑惑,泛型信息怎么表示啊?
常量池的通用格式如下:
目前 JVM8 中一共用 14 种常量类型,分别如下:
我们知道要使用一个字段或者调用一个方法,就必须知道字段或者方法所属类符号引用,和字段的名字和类型,方法的名字和方法参数类型以及方法返回值类型。
但是我们知道类是能继承的,那么子类调用父类的方法或者字段,这里的所属类符号引用,到底是子类本身还是父类的呢?
我们知道类,方法,字段都有不同的访问标志,在 Class 文件 中使用一个 u2 类型数据项来存储,也就是最多可以有 16 个不同标志位。
在类,方法,字段中有相同的标志,也有不同的标志,总体规划,我们可以借助 Modifier 类的源码来了解:
在 Modifier 类中,类的访问标志:
我们知道在 java 中类可以用的修饰符有: public , protected , private , abstract , static , final , strictfp 。
但是我们再看 Class 文件 中类的访问标志:
仔细看,你会发现有些不同点:
在 Modifier 类中,字段的访问标志:
我们知道在 java 中字段可以用的修饰符有: public , protected , private , static , final , transient 和 volatile 。
但是我们再看 Class 文件 中字段的访问标志:
Class 文件 中字段的访问标志和 java 中字段的修饰符差不多,只是多了 ACC_SYNTHETIC 和 ACC_ENUM 两个标志。
在 Modifier 类中,方法的访问标志:
我们知道在 java 中方法可以用的修饰符有:
public , protected , private , abstract , static , final , synchronized , synchronized 和 strictfp 。
但是我们再看 Class 文件 中方法的访问标志:
字段详情 field_info 的格式如下:
方法详情 method_info 的格式如下:
关于 Class 文件 中属性相关信息,我们再后面章节介绍。
我们可以通过 javap 的命令来阅读 Class 文件 中相关信息。
这个是最简单的一个类,没有任何字段和方法,只继承 Object 类,我们来看看它编译后的字节码信息,通过 javap -p -v T.class 的命令:
我们重点关注常量池相关信息,会发现虽然 T.class 很干净,但是也有 15 个常量,来我们依次分析:
与之前的例子相比较,多了一个字段和方法,那么得到的字节码信息如下:
但是你会发现常量池中怎么没有这个字段 name 的 CONSTANT_Fieldref_info 类型的常量呢?
那是因为我们没有使用这个字段。
多写了一个方法 test1 来调用 name 字段和 test 方法,那么得到的字节码信息如下:
这里定义一个父类 TParent ,有一个公共字段 name 和方法 say 。子类
4. jvm 基础篇-(4)-对象动态年龄计算规则
还没达到,大牛程度,可以看源码,看动态计算对象年龄的程度呦~
-XX:MaxTenuringThreshold=X X默认是15,15的含义是从eden-->survivor 对象年龄+1,survivor-->eden 对象年龄+1,直到年龄达到15后开始进入old Generation。
Hotspot遍历所有对象时, 按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了survivor区的一半时,取这个年龄和MaxTenuringThreshold中更小的一个值,作为新的晋升年龄阈值。
eg:
eg:Survivor区 = 64M,desired survivor = 32M,此时Survivor区中age<=2的对象累计大小为41M,41M大于32M,所以晋升年龄阈值被设置为2,下次Minor GC时将年龄超过2的对象被晋升到老年代。就会导致old generation 快速填满,触发old gc(old gc 有三处STW),所以这是建议调整 -XX:SurvivorRatio 参数。
1、如果固定按照MaxTenuringThreshold设定的阈值作为晋升条件: a)MaxTenuringThreshold设置的过大,原本应该晋升的对象一直停留在Survivor区,直到Survivor区溢出,一旦溢出发生,Eden+Svuvivor中对象将不再依据年龄全部提升到老年代,这样对象老化的机制就失效了。 b)MaxTenuringThreshold设置的过小,“过早晋升”即对象不能在新生代充分被回收,大量短期对象被晋升到老年代,老年代空间迅速增长,引起频繁的Major GC。分代回收失去了意义,严重影响GC性能。
2、相同应用在不同时间的表现不同:特殊任务的执行或者流量成分的变化,都会导致对象的生命周期分布发生波动,那么固定的阈值设定,因为无法动态适应变化,会造成和上面相同的问题。
总结来说,为了更好的适应不同程序的内存情况, 虚拟机并不总是要求对象年龄必须达到Maxtenuringthreshhold再晋级老年代 。
传送门 jvm-对象年龄(-XX:+PrintTenuringDistribution)
5. 急求深入理解Java虚拟机JVM高级特性与最佳实践 源码
这方面的书我倒是没有看过 ,但是我看过一半的 java 。。。。编程思想 挺不错 很厚 讲java 讲的很到位 那本书适合 开发2-4年java程序员看 我推荐你看下 对要是找到 关于java虚拟机的 源码和高级特性 最好也给我一份 谢谢 研究研究
6. JVM-安全点
Total time for which application threads were stop 超级长时间,这行日志代表什么,以及为什么时间会这么长
当GC发生时,每个线程只有进入了SafePoint才算是真正挂起,也就是真正的停顿,这个日志的含义是整个GC过程中STW的时间,配置了 -XX:+PrintGCApplicationStoppedTime 这个参数才会打印这个信息。
重点: 第一个 2.81 seconds 是JVM启动后的秒数,第二个 2.6 seconds 是 JVM发起STW的开始到结束的时间。特别地,如果是GC引发的STW,这条内容会紧挨着出现在GC log的下面。
有关安全点的详细说明,请移步:
JVM源码分析之安全点safepoint
[Java JVM] Hotspot GC研究- GC安全点 (Safepoint&Stop The World)
等待所有用户线程进入安全点后并阻塞,做一些全局性操作的行为。
配置 -XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1 参数,虚拟机会打印如下日志文件:
RevokeBias、BulkRevokeBias、偏向锁取消情况。
Deoptimize、
G1IncCollectionPause GC GC 执行情况。
分析 -XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1 产生的日志信息基本上STW的原因都是RevokeBias或者BulkRevokeBias。这个是撤销偏向锁操作,虽然每次暂停的 时间很短,但是特别频繁出现也会很耗时。
一些高并发的系统中,禁掉JVM偏向锁优化,可以提升系统的吞吐量 。禁用偏向锁的参数为: -XX:-UseBiasedLocking
R大分析类似情况
调优建议
各种JVM参数说明
stw分析
R大的博客
安全点 stw说明
偏向锁
7. 怎样在ide中进行jvm源码的调试
按照的方式配置好Mingw32,将其安装至c:\mingw
将Insight解压至c:\insight
'make clean',删除所有的objs,重置编译环境
'make SYMBOLS=1',编译mame,别忘了符号编译选项'SYMBOLS=1'
启动C:\insight\bin\insight.exe
菜单File->Target Settings->Connection->Target,选择'Exec'
在下面的ExecArguments里面添上mame的命令行启动参数,如ddragon2
File->Open,加载刚刚编译好的mame.exe
Run->Run,启动程序,然后便可以设置断点、单步跟踪了
8. JVM原理是什么
JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境.
1.创建JVM装载环境和配置
2.装载JVM.dll
3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例
4.调用JNIEnv实例装载并处理class类。
9. JVM源码分析之一个Java进程究竟能创建多少线程
线程大家都熟悉,new Thread().start()即会创建一个线程,这里我首先指出一点new Thread()其实并不会创建一个真正的线程,只有在调用了start方法之后才会创建一个线程,这个大家分析下Java代码就知道了
Thread的构造函数是纯Java代码,start方法会调到一个native方法start0里,而start0其实就是JVM_StartThread这个方法!
10. 简述jvm工作原理
Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。
运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。
Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上。
在Java平台的结构中, 可以看出,Java虚拟机(JVM) 处在核心的位置,是程序与底层操作系统和硬件无关的关键。它的下方是移植接口,移植接口由两部分组成:适配器和Java操作系统, 其中依赖于平台的部分称为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;在JVM 的上方是Java的基本类库和扩展类库以及它们的API, 利用Java API编写的应用程序(application) 和小程序(Java applet) 可以在任何Java平台上运行而无需考虑底层平台, 就是因为有Java虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java 的平台无关性。
JVM在它的生存周期中有一个明确的任务,那就是运行Java程序,因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。下面我们从JVM的体系结构和它的运行过程这两个方面来对它进行比较深入的研究。
1、Java虚拟机的体系结构
·每个JVM都有两种机制:
①类装载子系统:装载具有适合名称的类或接口
②执行引擎:负责执行包含在已装载的类或接口中的指令
·每个JVM都包含:
方法区、Java堆、Java栈、本地方法栈、指令计数器及其他隐含寄存器
2、Java代码编译和执行的整个过程
也正如前面所说,Java代码的编译和执行的整个过程大概是:开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。
(1)Java代码编译是由Java源码编译器来完成,也就是Java代码到JVM字节码(.class文件)的过程。
2)Java字节码的执行是由JVM执行引擎来完成
Java代码编译和执行的整个过程包含了以下三个重要的机制:
·Java源码编译机制
·类加载机制
·类执行机制
(1)Java源码编译机制
Java 源码编译由以下三个过程组成:
①分析和输入到符号表
②注解处理
③语义分析和生成class文件
最后生成的class文件由以下部分组成:
①结构信息:包括class文件格式版本号及各部分的数量与大小的信息
②元数据:对应于Java源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池
③方法信息:对应Java源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息
(2)类加载机制 JVM的类加载是通过ClassLoader及其子类来完成的