- 浏览: 371992 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (292)
- jbpm3.2 (4)
- hibernate (1)
- struts (2)
- spring (7)
- oracle (20)
- TCP/UDP (3)
- SpringSide (4)
- maven (4)
- eclipse插件 (11)
- 模板引擎 (2)
- javascript (4)
- 设计模式 (2)
- 工作中遇到异常及解决 (3)
- java文件编译问题 (1)
- ehcache应用 (1)
- java反射 (1)
- jbpm4 (1)
- Google-Gson (1)
- Jquery (6)
- XML (5)
- 工作记事 (2)
- flash builder 4 (1)
- Lucene (8)
- struts2 (1)
- AspectJ (1)
- spring proxool连接池配置 (1)
- StringUtils (1)
- spring security (5)
- JAVA点滴 (9)
- jbpm4.3 (1)
- ACL (0)
- 线程 (7)
- Java线程:新特征-线程池 (1)
- MemCache (5)
- compass (0)
- NIO (2)
- zookeeper (4)
- 并发 (2)
- redis (9)
- Nginx (5)
- jvm (1)
- 互联网 (24)
- shell (3)
- CAS (1)
- storm (4)
- 数据结构 (3)
- MYSQL (3)
- fsdfsdfsd (0)
- hadoop (19)
- hive (3)
- IntelliJ (3)
- python (3)
- 23423 (0)
- spark (7)
- netty (9)
- nmon (1)
- hbase (8)
- cassandra (28)
- kafka (2)
- haproxy (3)
- nodejs (3)
- ftp (1)
最新评论
-
记忆无泪:
遇到这个问题我用的sed -i 's/\r$//' /mnt/ ...
CentOS6 Shell脚本/bin/bash^M: bad interpreter错误解决方法 -
alenstudent:
Windows 下Nexus搭建Maven私服 -
dandongsoft:
lucene3+IK分词器 改造 lucene2.x+paoding -
duanyanrui:
学习了,支持
Google-Gson -
yscyfy:
这是你直接翻译过来的???
Google-Gson
转载
通过jps -lv 获取到本地的一个JVM实例进程。再通过jstack pid > thread.txt ,把stack trace输出到thread.txt文件中。
- 2012-08-28 23:16:39
- Full thread dump OpenJDK Client VM (19.0-b09 mixed mode, sharing):
- "Attach Listener" daemon prio=10 tid=0xb3da5400 nid=0x13ea waiting on condition [0x00000000]
- java.lang.Thread.State: RUNNABLE
- "Worker-15" prio=10 tid=0x09b7b400 nid=0x12f2 in Object.wait() [0xb30f9000]
- java.lang.Thread.State: TIMED_WAITING (on object monitor)
- at java.lang.Object.wait(Native Method)
- at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:188)
- - locked <0x6e5f87c0> (a org.eclipse.core.internal.jobs.WorkerPool)
- at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:220)
- at org.eclipse.core.internal.jobs.Worker.run(Worker.java:50)
- "Worker-12" prio=10 tid=0x09910c00 nid=0x12a0 in Object.wait() [0xb4026000]
- java.lang.Thread.State: TIMED_WAITING (on object monitor)
- at java.lang.Object.wait(Native Method)
- at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:188)
- - locked <0x6e5f87c0> (a org.eclipse.core.internal.jobs.WorkerPool)
- at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:220)
- at org.eclipse.core.internal.jobs.Worker.run(Worker.java:50)
- .......省略
- "Low Memory Detector" daemon prio=10 tid=0x097eb000 nid=0xa9f runnable [0x00000000]
- java.lang.Thread.State: RUNNABLE
- "CompilerThread0" daemon prio=10 tid=0x097e9000 nid=0xa9e waiting on condition [0x00000000]
- java.lang.Thread.State: RUNNABLE
- "Signal Dispatcher" daemon prio=10 tid=0x097e7400 nid=0xa9d runnable [0x00000000]
- java.lang.Thread.State: RUNNABLE
- "Finalizer" daemon prio=10 tid=0x097e4000 nid=0xa9c in Object.wait() [0xb4dd1000]
- java.lang.Thread.State: WAITING (on object monitor)
- at java.lang.Object.wait(Native Method)
- at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133)
- - locked <0x6e2e02f8> (a java.lang.ref.ReferenceQueue$Lock)
- at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149)
- at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)
- "Reference Handler" daemon prio=10 tid=0x097df400 nid=0xa9b in Object.wait() [0xb4e22000]
- java.lang.Thread.State: WAITING (on object monitor)
- at java.lang.Object.wait(Native Method)
- at java.lang.Object.wait(Object.java:502)
- at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- - locked <0x6e2e0098> (a java.lang.ref.Reference$Lock)
- "main" prio=10 tid=0x097b0400 nid=0xa99 runnable [0xbf8b9000]
- java.lang.Thread.State: RUNNABLE
- at org.eclipse.swt.internal.gtk.OS.Call(Native Method)
- at org.eclipse.swt.widgets.Display.sleep(Display.java:4069)
- at org.eclipse.ui.application.WorkbenchAdvisor.eventLoopIdle(WorkbenchAdvisor.java:364)
- at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor.eventLoopIdle(IDEWorkbenchAdvisor.java:917)
- at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2697)
- at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
- at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
- at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
- at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
- at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
- at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
- at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
- at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
- at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
- at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
- at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
- at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
- at java.lang.reflect.Method.invoke(Method.java:616)
- at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
- at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
- at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
- "VM Thread" prio=10 tid=0x097dd800 nid=0xa9a runnable
- "GC task thread#0 (ParallelGC)" prio=10 tid=0x08726800 nid=0x1e30 runnable
- "GC task thread#1 (ParallelGC)" prio=10 tid=0x08727c00 nid=0x1e31 runnable
- "VM Periodic Task Thread" prio=10 tid=0x097ed400 nid=0xaa0 waiting on condition
- JNI global references: 2131
上面的stack trace一共可以拆解成5个部分。
第一部分: Full thread dump identifier
可以看到dump时间,虚拟机的信息。
第二部分: Java EE middleware, third party & custom application Threads
- "Worker-15" prio=10 tid=0x09b7b400 nid=0x12f2 in Object.wait() [0xb30f9000]
- java.lang.Thread.State: TIMED_WAITING (on object monitor)
- at java.lang.Object.wait(Native Method)
- at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:188)
- - locked <0x6e5f87c0> (a org.eclipse.core.internal.jobs.WorkerPool)
- at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:220)
- at org.eclipse.core.internal.jobs.Worker.run(Worker.java:50)
此处是我们最为关心的地方,也是通过stack trace查找问题的地方,每个item的具体含义是
-Thread name: "Worker-15"
-线程优先级: prio=10
-java线程的identifier:tid=0x09b7b400
-native线程的identifier: nid=0x12f2
-线程的状态: in Object.wait() java.lang.Thread.State: TIMED_WAITING (on object monitor)
-线程栈起始地址:[0xb30f9000]
Java线程和Native线程,也就是tid和nid的区别?
VM是加载并执行字节码的机器,这个处理不对应具体硬件,它完全由软件来实现。虚拟机并不是直接跑在宿主的cpu上,中间还隔着宿主的操作系统。
虚拟机的职责是:翻译字节码,把它翻译成一系列的动作(内存操作)和系统调用(比如输入输出)。举个例子:当在java里请求与某台远程机器建立socket连接时,java虚拟机本身是不能完成这一工作的(协议栈是在操作系统内实现的),所以它需要系统调用。要明白这个,还需要知道JRE和JVM的关系。JRE是JVM的环境,一个应用程序就是一个JVM实例。一个机器上一般同时只有一个JRE环境,但是可以同时有多个JVM实例。不同的操作系统和CPU架构有不同的JRE。JRE包含了最基本的类库,当然包括和操作系统打交道的Native库,比如windows下的dll文件,linux下的so文件。JVM实例解析字节码的成JVM中的指令集,再通过Native方法进行操作系统层面的系统调用。下面的图能比较清楚的说明问题。
JVM线程如何创建
当然是通过Native库的 native方法。JVM的线程最终是通过操作系统的线程来完成系统调用的。针对Java开发者来说,发号施令的是JVM 线程,具体干藏活累活的却是操作系统线程。不同操作系统上,JVM创建本地线程依赖的native库也不同。具体可参考下面的的文章。http://jackyhongvip.iteye.com/blog/1338610
JVM线程状态
状态有Runnable、Wait on condition、Waiting for monitor entry 和 in Object.wait()。
Runnable:不解释
Wait on condition:该状态出现在线程等待某个条件的发生。具体是什么原因,可以结合 stacktrace来分析。最常见的情况是线程在等待网络的读写。如果网络数据没准备好,线程就等待在那里。另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。
Waiting for monitor entry 和 in Object.wait():这两种情况在多线程的情况下经常出现。Java是通过Monitor来实现线程互斥和协作(有些把Monitor直译成锁,我认为不妥,不是还有Lock嘛)。具体Monitor的深入理解见 http://www.cnblogs.com/tomsheep/archive/2010/06/09/1754419.html
但是可以理解成Monitor是一个对象或者class所拥有的锁,每个对象和class有且仅有一个。见下图.
每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。
在 “ Entry Set”里面的线程都等待拿到Monitor,拿到了线程就成为了Runnable线程,否则就会一直处于处于 “waiting for monitor entry”。一段代码作为例子
- public class MyThread implements Runnable{
- public void run() {
- synchronized(this) {
- for (int i = 0; i < 1; i--) {
- System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
- }
- }
- }
- public static void main(String[] args) {
- MyThread t1 = new MyThread();
- Thread ta = new Thread(t1, "A");
- Thread tb = new Thread(t1, "B");
- ta.start();
- tb.start();
- }
- }
大家一看就知道,B线程肯定是“千年老二“,永远拿不到Monitor了。
对应的stack:
- "B" prio=10 tid=0x0969a000 nid=0x11d6 waiting for monitor entry [0x8bb22000]
- java.lang.Thread.State: BLOCKED (on object monitor)
- at org.marshal.MyThread.run(MyThread.java:7)
- - waiting to lock <0x94757078> (a org.marshal.MyThread)
- at java.lang.Thread.run(Thread.java:636)
- "A" prio=10 tid=0x09698800 nid=0x11d5 runnable [0x8bb73000]
- java.lang.Thread.State: RUNNABLE
- at java.io.FileOutputStream.writeBytes(Native Method)
- at java.io.FileOutputStream.write(FileOutputStream.java:297)
- at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
- at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
- - locked <0x947571b0> (a java.io.BufferedOutputStream)
- at java.io.PrintStream.write(PrintStream.java:449)
- - locked <0x94757190> (a java.io.PrintStream)
- at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:220)
- at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:290)
- at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:103)
- - locked <0x947572a0> (a java.io.OutputStreamWriter)
- at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
- at java.io.PrintStream.write(PrintStream.java:494)
- - locked <0x94757190> (a java.io.PrintStream)
- at java.io.PrintStream.print(PrintStream.java:636)
- at java.io.PrintStream.println(PrintStream.java:773)
- - locked <0x94757190> (a java.io.PrintStream)
- at org.marshal.MyThread.run(MyThread.java:8)
- - locked <0x94757078> (a org.marshal.MyThread)
- at java.lang.Thread.run(Thread.java:636)
<0x94757078> 就是两个线程争夺的Monitor。
在 “Wait Set”里面的线程都如饥似渴地等待拿到Monitor。他们是怎么进入到“Wait Set”的呢?当一个线程拿到了Monitor,但是在其他资源没有到位的情况下,调用同步锁对象(一般是synchronized()内的对象)的 wait() 方法,放弃了 Monitor,它就进入到了 “Wait Set”队列。只有当其他线程通过notify() 或者 notifyAll(),释放了同步锁后,这个线程才会有机会重新去竞争Monitor。在stack中,它表现的状态是in Object.wait()。修改上面的代码public class WaitThread implements Runnable{
- public void run() {
- synchronized(this) {
- try {
- this.wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- public static void main(String[] args) {
- WaitThread t1 = new WaitThread();
- Thread ta = new Thread(t1, "A");
- Thread tb = new Thread(t1, "B");
- ta.start();
- tb.start();
- }
对应的stack:
- "B" prio=10 tid=0x08173000 nid=0x1304 in Object.wait() [0x8baf2000]
- java.lang.Thread.State: WAITING (on object monitor)
- at java.lang.Object.wait(Native Method)
- - waiting on <0xa9cb50e0> (a org.marshal.WaitThread)
- at java.lang.Object.wait(Object.java:502)
- at org.marshal.WaitThread.run(WaitThread.java:8)
- - locked <0xa9cb50e0> (a org.marshal.WaitThread)
- at java.lang.Thread.run(Thread.java:636)
- "A" prio=10 tid=0x08171c00 nid=0x1303 in Object.wait() [0x8bb43000]
- java.lang.Thread.State: WAITING (on object monitor)
- at java.lang.Object.wait(Native Method)
- - waiting on <0xa9cb50e0> (a org.marshal.WaitThread)
- at java.lang.Object.wait(Object.java:502)
- at org.marshal.WaitThread.run(WaitThread.java:8)
- - locked <0xa9cb50e0> (a org.marshal.WaitThread)
- at java.lang.Thread.run(Thread.java:636)
A和B线程都进入了”wait set“。B线程也拿到过这个Monitor,因为A线程释放过了,这也验证上面的话,他们都在等待得而复失的<0xa9cb50e0>。
基于我们经常讨论到的死锁问题,构造一段代码如下
- public class DeadThread implements Runnable{
- private Object monitor_A = new Object();
- private Object monitor_B = new Object();
- public void method_A(){
- synchronized(monitor_A) {
- synchronized(monitor_B) {
- System.out.println(Thread.currentThread().getName()+" invoke method A");
- }
- }
- }
- public void method_B(){
- synchronized(monitor_B) {
- synchronized(monitor_A) {
- System.out.println(Thread.currentThread().getName()+" invoke method B");
- }
- }
- }
- public void run() {
- for(int i=0;i<1;i--){
- method_A();
- method_B();
- }
- }
- public static void main(String[] args) {
- DeadThread t1 = new DeadThread();
- Thread ta = new Thread(t1, "A");
- Thread tb = new Thread(t1, "B");
- ta.start();
- tb.start();
- }
- }
对应的stack:
- "B" prio=10 tid=0x0898d000 nid=0x269a waiting for monitor entry [0x8baa2000]
- java.lang.Thread.State: BLOCKED (on object monitor)
- at org.marshal.DeadThread.method_A(DeadThread.java:11)
- - waiting to lock <0xaa4d6f88> (a java.lang.Object)
- - locked <0xaa4d6f80> (a java.lang.Object)
- at org.marshal.DeadThread.run(DeadThread.java:28)
- at java.lang.Thread.run(Thread.java:636)
- "A" prio=10 tid=0x0898b800 nid=0x2699 waiting for monitor entry [0x8baf3000]
- java.lang.Thread.State: BLOCKED (on object monitor)
- at org.marshal.DeadThread.method_B(DeadThread.java:19)
- - waiting to lock <0xaa4d6f80> (a java.lang.Object)
- - locked <0xaa4d6f88> (a java.lang.Object)
- at org.marshal.DeadThread.run(DeadThread.java:29)
- at java.lang.Thread.run(Thread.java:636)
同时注意到,在stack trace尾部信息
- Found one Java-level deadlock:
- =============================
- "B":
- waiting to lock monitor 0x089615d8 (object 0xaa4d6f88, a java.lang.Object),
- which is held by "A"
- "A":
- waiting to lock monitor 0x08962258 (object 0xaa4d6f80, a java.lang.Object),
- which is held by "B"
- Java stack information for the threads listed above:
- ===================================================
- "B":
- at org.marshal.DeadThread.method_A(DeadThread.java:11)
- - waiting to lock <0xaa4d6f88> (a java.lang.Object)
- - locked <0xaa4d6f80> (a java.lang.Object)
- at org.marshal.DeadThread.run(DeadThread.java:28)
- at java.lang.Thread.run(Thread.java:636)
- "A":
- at org.marshal.DeadThread.method_B(DeadThread.java:19)
- - waiting to lock <0xaa4d6f80> (a java.lang.Object)
- - locked <0xaa4d6f88> (a java.lang.Object)
- at org.marshal.DeadThread.run(DeadThread.java:29)
- at java.lang.Thread.run(Thread.java:636)
- Found 1 deadlock.
stack中直接报告了Java级别的死锁,够智能吧。
第三部分:HotSpot VM Thread
- "Low Memory Detector" daemon prio=10 tid=0x097eb000 nid=0xa9f runnable [0x00000000]
- java.lang.Thread.State: RUNNABLE
- "CompilerThread0" daemon prio=10 tid=0x097e9000 nid=0xa9e waiting on condition [0x00000000]
- java.lang.Thread.State: RUNNABLE
JVM管理的内部线程,这些内部线程都是来执行native操作的,可以不必太关注。
第四部分: HotSpot GC Thread
- "GC task thread#0 (ParallelGC)" prio=10 tid=0x08726800 nid=0x1e30 runnable
- "GC task thread#1 (ParallelGC)" prio=10 tid=0x08727c00 nid=0x1e31 runnable
当虚拟机打开了parallel GC,这些线程就会定期地GC清理。
第五部分:JNI global references count
JNI (Java Native Interface)全局引用也是受垃圾回收器管理。它的作用是防止回收到那些在native代码上还是被引用的,但是在java代码中却没有存活必要的引用。对于防止因为应用代码中直接使用native库或者第三方的一些监控工具的内存泄漏有非常大的帮助。
参考文献:
http://peiliping.ixiezi.com/2012/04/15/jvm-jstack%E7%94%A8%E6%B3%95/
http://www.cnblogs.com/tomsheep/archive/2010/06/09/1754419.html
http://www.javacodegeeks.com/2012/03/jvm-how-to-analyze-thread-dump.html
http://blog.csdn.net/fenglibing/article/details/6411940
发表评论
-
无备案小站的最好的广告收益来源
2020-08-09 10:52 248现在无备案的无名小站运营维持真的很难,广告难接,各大广告联盟 ... -
老番茄访问IP突破1W
2019-11-13 10:19 5感谢大家,老番(www.laofanqie.com) 用户访问 ... -
Nmon工具的使用以及通过nmon_analyse生成分析报表
2016-09-07 11:44 391Nmon工具的使用以及通过nmon_a ... -
用“逐步排除”的方法定位Java服务线上“系统性”故障
2015-08-27 19:12 736一、摘要 由于硬件问题、系统资源紧缺或者程序本身的BUG, ... -
simple-spring-memcached简介
2015-07-09 15:06 421memcached是一款非常优秀的分布式缓存工具,有效提升了 ... -
Tomcat 7 的新JDBC连接池的使用说明
2015-06-28 22:55 1316Tomcat 7 的JDBC连接池实 ... -
CentOS安装JDK1.6
2015-04-01 11:56 10321、获得程序包 jdk-6u16-dlj-linux- ... -
abtest
2014-12-01 11:51 1039Apache服务自带了应该用于压力测试的工具ab(Apach ... -
mysql优化
2014-08-29 11:36 60619195.cn 手游网站mysql 优化一: v ... -
怎么快速搭建游戏网站,手游网站,手机应用网站??
2014-07-28 13:14 1599大家好,作为19195手游 ... -
mysql备份还原
2014-06-13 11:31 2备份数据库 -
centos6利用yum安装php mysql
2014-05-18 13:47 915一、安装mysql #yum -y install my ... -
Centos如何挂载硬盘
2014-05-15 13:03 771远程SSH登录上Centos服务器后,进行如下操作提醒:挂 ... -
远程监控JVM--VisualVM
2013-01-09 18:26 1168对于使用命令行远程监控jvm太麻烦?那可以试试sun ... -
聊聊并发(五)原子操作的实现原理
2013-01-07 17:50 01 引言 原子(atom)本意是“不能被进一步分 ... -
聊聊并发(四)深入分析ConcurrentHashMap
2013-01-07 17:48 0术语定义 术语 英文 解释 哈希算法 ... -
聊聊并发(三)Java线程池的分析和使用
2013-01-07 17:45 8351. 引言 合理利用线程池能够带来三个好处。第一 ... -
聊聊并发(二)Java SE1.6中的Synchronized
2013-01-07 17:42 9111 引言 在多线程并发编程中Synchronized一 ... -
聊聊并发(一)深入分析Volatile的实现原理
2013-01-07 17:41 808作者http://ifeve.com 引言 在 ... -
JVM调优汇总
2012-12-17 12:40 1033参考网址 http://pengjiaheng ...
相关推荐
每一个线程都有自己的 PC 寄存器(程序计数器)和 Java 堆栈(Java stack)。PC 寄存器保存线程执行的下一条指令。Java 堆栈保存了一个线程调用方法时的状态,包括本地变量、调用方法的参数、返回值、处理的中间变量...
### Java SE8虚拟机(JVM)结构解析 Java SE8版本对Java虚拟机(JVM)的结构进行了详尽的规定,本文将围绕给定文件提供的信息深入解析JVM的关键组成部分及其功能,包括PC寄存器、Java虚拟机栈、方法区、堆、运行时常量...
1. **类加载子系统**(Class Loader Subsystem):负责将Java类加载到内存中,并对它们进行验证、解析和初始化。每个Java应用程序都有一个类加载器子系统,该子系统包括: - **引导类加载器**(Bootstrap Class ...
JVM的动态编译是提升性能的关键,本章会介绍HotSpot虚拟机的编译策略,如OSR(On-Stack Replacement)和逃逸分析,以及如何通过-XX选项调整编译参数。 6. **第10章:多线程与并发** 在Java中,多线程编程是常见...
- **运行时数据区(Runtime Data Areas)**:包括方法区(Method Area)、堆(Heap)、Java栈(Java Stack)、本地方法栈(Native Method Stack)、程序计数器(Program Counter)。 - **执行引擎(Execution ...
### Java虚拟机(JVM)深度解析 #### 引言 Java虚拟机(JVM),作为Java技术的核心组件之一,是执行Java字节码的虚拟环境。本文将深入探讨JVM的基本概念、工作原理以及其在程序生命周期中的作用,帮助读者全面理解Java...
类加载的过程包括加载、验证、准备、解析和初始化五个阶段。 垃圾回收(Garbage Collection)是JVM中一个重要的自动化内存管理机制。它负责回收堆内存中不再使用的对象实例,从而防止内存泄漏。不同的JVM实现采用...
主要包括方法区(Method Area)、堆(Heap)、Java栈(Java Stack)、本地方法栈(Native Method Stack)、程序计数器(Program Counter)五个部分。 4. 垃圾回收机制:JVM中的垃圾回收主要是针对堆区进行的。垃圾...
- **操作数栈(Operand Stack)**:主要用于保存计算过程中产生的中间结果,也用来存放操作数。 - **动态链接(Dynamic Link)**:包含一个指向运行时常量池中该栈帧所属方法的引用。 - **方法返回地址(Return ...
类的加载是指将类的.class文件中的二进制数据读入到内存中,对其进行字节码校验、解析和初始化,最终转化为可以被虚拟机直接使用的Java类型。类的加载过程主要包括加载、验证、准备、解析和初始化五个阶段。 - **...
4. **虚拟机栈(Virtual Machine Stack)** - 虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。 5. **本地方法栈...
1. **内存模型**:JVM内存分为堆内存(Heap)、栈内存(Stack)、方法区(Method Area)、程序计数器(PC Register)和本地方法栈(Native Method Stack)。堆是存储对象实例的主要区域,栈则用于存储方法调用时的...
- 类加载过程包括加载、验证、准备、解析和初始化五个阶段。 2. **运行时数据区** - 这是JVM的核心之一,负责管理运行时的各种内存区域。 - 包括方法区、堆、栈、本地方法栈和程序计数器。 3. **执行引擎** - ...
异常处理机制允许程序优雅地处理错误,栈跟踪(StackTrace)提供详细的出错位置信息。 9. **JNI与Native方法** 通过Java Native Interface(JNI)可以调用C/C++代码,实现Java与本地库的交互。 10. **JVM内存...
* 解析(Resolution):将符号引用替换为直接引用。 * 初始化(Initialization):执行类的静态初始化器。 *卸载(Unloading):卸载 Class 文件。 类加载器 Java 中的类加载器主要包括以下几种: * 启动类加载器...
类加载过程主要包括加载、验证、准备、解析和初始化五个阶段。其中,类的初始化阶段是执行类构造器`()`的地方,负责对类变量进行初始值设置。 #### 字节码解释与JIT编译 Java程序最初以字节码形式运行,由解释器...
- 类加载器负责读取字节码文件(.class),解析出构成类或接口的数据,并生成代表类或接口的`java.lang.Class`对象。 8. **更快的类加载(Faster Class Loading)** - 快速类加载是指通过缓存机制来加速类的加载过程...
通过对Java虚拟机JVM的基本概念、架构以及内存管理机制的深入解析,我们可以更好地理解Java程序的执行过程。掌握JVM的工作原理有助于开发者编写更高效、更稳定的Java应用程序,并能有效地解决常见的内存溢出问题。
3. **内存管理**:JVM有自己的一套内存模型,包括堆内存(Heap)、方法区(Method Area)、栈内存(Stack)、本地方法栈(Native Method Stack)和程序计数器(PC Register)。堆内存主要存储对象实例,方法区存储类...