- 浏览: 1011368 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (826)
- 硬件 (8)
- 软件 (24)
- 软件工程 (34)
- JAVA (229)
- C/C++/C# (77)
- JavaScript (8)
- PHP (1)
- Ruby (3)
- MySQL (14)
- 数据库 (19)
- 心情记事 (12)
- 团队管理 (19)
- Hadoop (1)
- spring (22)
- mybatis(ibatis) (7)
- tomcat (16)
- velocity (0)
- 系统架构 (6)
- JMX (8)
- proxool (1)
- 开发工具 (16)
- python (10)
- JVM (27)
- servlet (5)
- JMS (26)
- ant (2)
- 设计模式 (5)
- 智力题 (2)
- 面试题收集 (1)
- 孙子兵法 (16)
- 测试 (1)
- 数据结构 (7)
- 算法 (22)
- Android (11)
- 汽车驾驶 (1)
- lucene (1)
- memcache (12)
- 技术架构 (7)
- OTP-Erlang (7)
- memcached (17)
- redis (20)
- 浏览器插件 (3)
- sqlite (3)
- Heritrix (9)
- Java线程 (1)
- scala (0)
- Mina (6)
- 汇编 (2)
- Netty (15)
- libevent (0)
- CentOS (12)
- mongod (5)
- mac os (0)
最新评论
-
kingasdfg:
你这里面存在一个错误添加多个任务 应该是这样的 /** * ...
Quartz的任务的临时启动和暂停和恢复【转】 -
kyzeng:
纠正一个错误,long型对应的符号是J,不是L。
Jni中C++和Java的参数传递 -
zhaohaolin:
抱歉,兄弟,只是留下作记录,方便学习,如果觉得资料不好,可以到 ...
netty的个人使用心得【转】 -
cccoooccooco:
谢谢!自己一直以为虚机得使用网线才可以与主机连接呢。。
主机网卡无网线连接与虚拟机通信 -
yuqilin001:
要转别人的东西,请转清楚点嘛,少了这么多类,误人子弟
netty的个人使用心得【转】
以下继续探讨,说说jvm的线程(thread)及其执行中和内存相关的问题。but今天是写不完了,请保持关注,先写个预告栏咯
记
得当年学java之初,总是很鄙夷它,因为那时候对c/c++很痴迷,结果呢,第一个多线程程序还是拿java写出来的。而线程(thread),本是操
作系统的所提供/支持的,所以当初有一段时间,我总在怀疑我那java程序创建的线程到底是不是真正的操作系统线程,现在看来很可笑。
题外,再继续质疑一下:
在
有些平台上,比如Linux或者大部分的unix,只有进程而没有线程的概念的,但这些平台上,进程间通讯的手段极其发达,所以jvm会用进程模拟线程,
效果也是一样的。不过,也有一些平台如sorlaris,在java线程和os内核线程间,存在着不是1对1的关系,实在让我挠头,容以后再去把它搞明
白。
简单的说,jvm如何实现多线程呢,首先要有os的支持包括变相的支持,那么jvm通过os提供线程接口创建新线程,这些新线程当然
还不能直接执行你的 thread对象的run方法,但它会拥有并执行属于该线程的一个java
interpreter实例或者上下文,java解释器再去执行你的run方法,当run方法结束(自然结束时),java
interpreter发现没有字节码可以解释了,也宣告结束,OS线程也就自然终结了。至于要实现线程的终止,挂起,恢复,也都可以从OS那里找到相应
的接口,这里不再细说,而主要关注对内存的影响,主要是java stack和native call等问题。
待续
续
当
执行引擎(即java interpreter,对应一个ExecEnv)开始解释执行一个java
method以前,它首先初始化自身,即分配自己的initial java
stack,栈开始时尺寸很小,随着使用的需要而扩展,存在一个400k的默认长度限制(
-Xss<size>可更改该值);ExecEnv有两个重要的标志(或指针),一个是pc,即程序计数器,另一个是optop,即栈顶,也是最上面一个操作数(即本地变量)的位置。
pc总是指向要执行的byte code(随着每一条byte code的执行,pc自动改变),而optop指向java stack的顶端(也随某些byte code的执行而改动)。当方法执行时,方法的invoker将pc指向method block的code
位,同时,在java stack里为该方法新建java frame(每一个方法在编译期就确定了运行它所需的最大stack
size,所以,新建java freame时,会按照这个size去检查java stack是否满足,若不足,则扩展java
stack,而java stack已经达到最大长度限制时,扩展失败,发生stack
overflow),准备工作完成后,还给ExecEnv继续解释和执行;当方法执行完毕时,一条ret字节指令将pc和optop送回前一个java
frame所记录的位置。所以,对于某个线程来说,其java stack完整的记录了所深入的每一层java method(每层一个java
frame),除了native method,本质上是因为c的堆栈不能记录。
以上是执行java method,若是native
method呢?很简单,native method在类加载时,即被jvm安排了一个native invoker在其method
block中,继而在ExecEnv执行一条call该native method的字节指令时,native
invoker被执行,如果是首次执行,那么这个native mothod的method block的code段尚未挂接,native invoker检查到这个信息,将根据method name和signature搜索系统中已加载的dll的合适挂接点,将找到的挂接点挂在code上,而后调用该code段即可(找不到挂接点,会发生什么异常你应该清楚)。过程中,除非你的native method中又反调了java method,那么,java stack将毫无变化。
再来关注一下native method的内存模型:native mthod自身的机器码code
存在于dll镜像(image)中;nm的本地变量存在于线程堆栈内(指native thread,和java
thread是绑定着的);nm用到的静态变量存在于dll的共享变量区中;nm制造的java对象(通过jni手段new来的)依然在java
heap;而nm声明的global ref以及local ref存放在jvm的native c
heap上。本地方法也会带来内存泄露(c的内存泄露,也可能是java heap的global ref的未释放),特别是c
heap的泄露,运行期是极难探测和定位的。
最后,说说调用深度过深(即java
stack会很长)带来的负面影响。在前一节,我们知道本地变量都寄存在java
stack中。如果调用深度过深,特别是jvm长时间运行在较高深度调用的情形下,意味着在栈上的各frame中,存在着很多变量,它们中的引用类型将一
直保持对java heap上对应对象的引用而导致gc器始终不能释放它们;其次,较长的java
stack也给gc器造成了较多的扫描时间(为何要扫描后面再说);第三,method
call本身也是一种时间开销,对于很短小的method,call它比它本身代码执行的时间还要多,好比机关枪打蚊子,这也是现代编译器非常讲究
inline优化的原因。
发表评论
-
A Collection of JVM Options
2011-06-24 12:59 1158A Collection of JVM Options ... -
java中堆(heap)和堆栈(stack)有什么区别
2011-05-10 14:29 893stack 和 heep 都是内存的一部分 stack 空间 ... -
JVM & Memory (5) final
2011-05-10 14:25 995先说tuning,gc有两个指标,一个是frequentcy( ... -
JVM & Memory (4) gc
2011-05-10 14:22 911不同的JVM实现对堆结构的设计有所不同,这里先说说共性的,然后 ... -
JVM & Memory (2) java.exe
2011-05-10 14:20 944上篇说到了关于java heap ... -
JVM & Memory (1) paging
2011-05-10 14:19 959近期看了一些有关JVM和内存的资料,为了避免遗忘,特在这里作一 ... -
JDK TOOLS
2011-05-10 14:15 813以下这几种工具(存在于 ... -
jvm日志分析工具应用
2011-05-10 14:14 2816涛涛学习笔记之gc日志分析工具 测试环境:xp+weblog ... -
JVM优化配置
2011-05-10 13:56 934OOM 这个缩写就是Java程 ... -
高手详细介绍JVM是什么?
2011-05-10 13:52 874首先这里澄清两个概念:JVM实例和JVM执行引擎实例,JVM实 ... -
JVM监控工具介绍
2011-03-22 14:25 891... -
正确认识java JVM与c/c++的执行效率
2011-03-22 10:43 1412认为Java 不能写JVM是完全错误的。JNode是一个用 ... -
Java虚拟机(JVM)参数配置说明
2011-03-22 10:26 986Java虚拟机(JVM)参数配置说明 ... -
解析 Java 类和对象的初始化过程
2011-03-21 23:40 909解析 Java 类和对象的初始化过程 由一个单态模式引出的问 ... -
JDK的概念、组成及JDK常用包
2011-03-18 22:09 1139JDK概述 JDK (Java Development ... -
安装JDK后JRE与JVM联系浅谈
2011-03-18 22:08 916安装JDK后JRE、JVM之间的 ... -
详细介绍什么是Java虚拟机
2011-03-18 22:07 841本文由浅入深,先从什么是Java虚拟机、Java虚拟机 ... -
认识Java虚拟机及其性能
2011-03-18 22:04 726Java虚拟机(Java virtual ... -
JVM GC调整优化过程全揭秘
2011-03-18 22:03 839JVM GC调整优化是以个极为复杂的过程,由于各个程序具备 ... -
Java虚拟机的研究与实现(图文)
2011-03-18 21:59 1033引言 Java 虚拟机本质是就是一个程序,当它在命令行 ...
相关推荐
3. Thread Dump:使用jstack命令获取线程快照,分析阻塞或死锁情况。 4. 监控GC日志:通过-XX:+PrintGC、-XX:+PrintGCDetails、-XX:+PrintGCDateStamps等参数,记录并分析垃圾收集行为。 5. 分析内存泄漏:利用内存...
jmap - JVM Memory Map Tool **用途**:生成虚拟机的内存映像文件,用于分析内存泄露等问题。 **命令格式**: ``` jmap [option] pid ``` **执行示例**: ``` jmap -dump:format=b,file=/tmp/dump3700.hprof ...
### Sun JVM原理与内存管理 #### 一、Sun JDK 1.6 GC (Garbage Collector) Sun JDK 1.6 的垃圾收集器(GC)是其内存管理的关键组成部分,它负责自动地回收不再使用的对象所占用的内存。本文将详细介绍Sun JDK 1.6 GC...
3. **jinfo(Configuration Info for Java)**:用于查看和修改JVM配置信息,如JVM选项、系统属性等,对于排查特定环境下的问题很有帮助。 4. **jhat(Java Heap Analysis Tool)**:当JVM生成堆转储文件后,jhat...
3. **Garbage Collection(GC)问题**:JVM的垃圾收集机制可能导致性能瓶颈。通过监控GC日志,我们可以分析GC行为,如暂停时间、内存分配情况等。 4. **类装载问题**:类装载器错误可能引发NoClassDefFoundError或...
- **直接内存(Direct Memory)**:不是JVM运行时数据区的一部分,但在某些场景下会被频繁使用,比如通过ByteBuffer的allocateDirect方法分配的内存。 #### 堆内存划分与回收 堆内存通常被划分为几个部分,包括...
3. **程序计数器**:这是一个非常小的内存区域,用于存储当前线程正在执行的字节码指令的地址。由于Java是多线程的,每个线程都有自己的程序计数器,这样可以确保线程在被调度时能准确地找到下一条要执行的指令。 4...
- **Thread Dump**:线程快照,记录当前所有线程的状态及调用栈信息。 - **Heap Dump**:堆快照,记录了堆内存中所有的对象及其相关信息。 #### 三、常用命令及应用场景 ##### 1. **top** - **命令格式**:`top` ...
3. **线程栈(Thread Stack)**:用于存储线程的局部变量、栈帧等。 #### 堆内存配置详解 堆内存是JVM管理的主要区域之一,也是最常发生内存溢出的地方。合理的堆内存配置可以显著提升应用性能。以下是一些重要的...
3. **垃圾回收**:JVM负责自动管理内存,当对象不再被引用时,垃圾回收器会回收其占用的空间。常见的垃圾收集算法有标记-清除、复制、标记-整理和分代收集等。新生代、老年代和持久代是根据对象生命周期进行划分的...
介绍了heap dump和thread dump,以及详细介绍dump工具Memory Analyzer的使用,最后讲解了Java对象的内存布局。
heap dump是Java虚拟机(JVM)在某个时间点对堆内存快照的记录,包含了所有对象及其引用关系。当应用程序出现性能问题或者内存耗尽时,生成heap dump文件至关重要。MAT可以打开并解析这些文件,为用户提供深入的内存...
- **Java内存模型(JMM, Java Memory Model)**:定义了线程之间的共享变量如何在内存中交互和同步的规则。 - **工作内存与主内存**:每个线程都有自己的工作内存,包含对共享变量的副本。线程间通过主内存交换信息...
《JVM调优总结》与《Java虚拟机:JVM高级特性与最佳实践》是两本深入探讨Java虚拟机(JVM)的书籍,对于Java开发者来说,它们提供了丰富的知识和实践经验,尤其对于想要理解JVM工作原理以及进行性能优化的专业人士更...
二、jstack (Java Thread Stack Trace) jstack用于查看JVM的线程堆栈信息,帮助诊断线程阻塞或死锁问题。基本语法: ``` jstack [option] pid ``` 选项通常包括: - `-l`:详细输出,包括锁信息。 例如,`jstack -l...
--total-memory :应用程序可用的总内存,通常用大小分类( B 、 K 、 M 、 G 、 T )表示 --loaded-class-count :应用程序运行时将加载的类数 --thread-count : 用户线程数 --jvm-options : JVM 选项,通常是JAVA...
"JVM堆内存分析工具"如HA(HeapAnalyzer)和MAT(Memory Analyzer Tool)就是专门为此设计的,它们能够帮助开发者深入洞察内存的分配、使用以及可能存在的内存泄漏问题。 首先,HA(HeapAnalyzer)通常是一个简单的...
Thread Dump,即线程快照,是指Java虚拟机(JVM)在某一时间点捕捉到的所有线程的状态快照。通过分析Thread Dump,我们可以了解到每个线程当时的运行情况,包括线程的运行状态、调用栈等关键信息,这对于理解系统内部...
- 直接内存(Direct Memory):使用Native方法直接分配堆外内存。 4. **垃圾收集** - 垃圾收集的基本概念与目标。 - 垃圾收集器类型:串行、并行、并发、G1、ZGC、Shenandoah等。 - 分代收集理论:年轻代、老...
主要包括主内存(Shared Memory)和每个线程的工作内存(Thread Local Memory),线程间通信必须通过主内存交换。 8. **垃圾收集与对象存活判定**: - 使用可达性分析算法,通过GC Roots来判断对象是否可达。如果...