- 浏览: 104543 次
- 性别:
- 来自: 武汉
-
最新评论
-
hatedance:
这个bytecodeInterpreter应该已经被遗弃了,现 ...
openjdk中的同步代码 -
Mr_lee_2012:
是啊,好文章,谢过。
java栈帧中的对象引用 -
ZangXT:
有些性能要求比较高的系统会考虑这一点的,典型的如JPC,尽量避 ...
java中调用接口及调用继承类效率区别 -
tinywind:
你有没有注意到load_classfile开始定义了个Reso ...
hotsphot中的ResourceArea -
qianli-2010:
java中调用接口及调用继承类效率区别
openjdk中的垃圾回收是一个庞大的课题,如何标记活动的对象,就涉及到了堆栈的、常量池的跟踪标记等,非常复杂。在此先做一个初步的分析。
先从System.java中的gc方法开始阅读。
public static void gc() {
Runtime.getRuntime().gc();
}
跟踪进去,其实调用到了jvm.cpp里面的JVM_GC(void)
{
if (!DisableExplicitGC) { //如果可以直接进行垃圾回收,则执行下面的一步, -XX:+DisableExplicitGC 选项可以关闭jvm的直接垃圾回收
Universe::heap()->collect(GCCause::_java_lang_system_gc);
}
}
垃圾回收的方式有多种,下面跟踪并发收集(ParallelScavengeHeap.cpp)。
void ParallelScavengeHeap::collect(GCCause::Cause cause) {
...........
VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause);
VMThread::execute(&op);
}
上面的exceute()方法,主要执行的是VM_ParallelGCSystemGC 的doit()方法,下面看看
void VM_ParallelGCSystemGC::doit() {
//在这主要看一下全部回收的代码
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
heap->invoke_full_gc(false);
}
下面是invoke_full_gc代码
inline void ParallelScavengeHeap::invoke_full_gc(bool maximum_compaction)
{
.......
PSMarkSweep::invoke(maximum_compaction);//从名字看出这个方法主要做标记、清除操作
}
跟踪进入上面方法
void PSMarkSweep::invoke(bool maximum_heap_compaction) {
.........
PSMarkSweep::invoke_no_policy(maximum_heap_compaction);
}
上面invoke_no_policy非常复杂,在这仅对其第一阶段的操作进行简单分析。
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
.........
//从根开始对强引用开始进行标记操作
Universe::oops_do(mark_and_push_closure());
ReferenceProcessor::oops_do(mark_and_push_closure());
JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles
//跟踪每个线程堆栈,对堆栈里面的对象引用进行跟踪
Threads::oops_do(mark_and_push_closure());
ObjectSynchronizer::oops_do(mark_and_push_closure());
FlatProfiler::oops_do(mark_and_push_closure());
Management::oops_do(mark_and_push_closure());
JvmtiExport::oops_do(mark_and_push_closure());
//跟踪常量池用到的每个类
SystemDictionary::always_strong_oops_do(mark_and_push_closure());
vmSymbols::oops_do(mark_and_push_closure());
}
简单提一下,上面用到的MarkAndPushClosure,它其实就是将对象打上标志,并将对象指针压入一个栈中。采用的是回调函数用法,由上面的oops_do调用。代码如下
{
if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
if (!obj->mark()->is_marked()) {
mark_object(obj); //对遍历到的对象进行标志
_marking_stack->push(obj); //对象入栈
}
}
}
好,回到前面,简单分析一下Threads::oops_do(mark_and_push_closure())。
void Threads::oops_do(OopClosure* f) {
for (JavaThread* p = _thread_list; p; p = X->next()){ //遍历所有用户线程
p->oops_do(f);
}
VMThread::vm_thread()->oops_do(f); //遍历vmThread
}
java对象的方法调用,其在方法内创建的局部变量都在线程堆栈内。javaThread::oops_do应该会对堆栈内的对象进行标记,下面看一下代码。
void JavaThread::oops_do(OopClosure* f) {
Thread::oops_do(f);
........
//下面是堆栈桢的遍历
for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
fst.current()->oops_do(f, fst.register_map());
}
........
}
void Frame::oops_do(OopClosure* f, RegisterMap* map) {
oops_do_internal(f, map, true);
}
void frame::oops_do_internal(OopClosure* f, RegisterMap* map, bool use_interpreter_oop_map_cache) {
if (is_interpreted_frame()) { //以解释桢为例
oops_interpreted_do(f, map, use_interpreter_oop_map_cache);
}
}
void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache) {
............
oops_interpreted_locals_do(f, max_locals, mask);
oops_interpreted_expressions_do(f, signature, is_static,
m->max_stack(),
max_locals, mask);
............
}
void frame::oops_interpreted_locals_do(OopClosure *f,
int max_locals,
InterpreterOopMap *mask) {
for (int i = 0; i < max_locals; i++ ) {
Tag tag = interpreter_frame_local_tag(i);
if (tag == TagReference) { //如果是对象引用,则进行标记,总算找到了
oop* addr = (oop*) interpreter_frame_local_at(i);
assert((intptr_t*)addr >= sp(), "must be inside the frame");
f->do_oop(addr);
}
}
堆栈里面存着基本类型及引用类型,它们的位置及垃圾回收算法是如何区分这些类型的,这个还需要进一步的分析。
发表评论
-
java动态代理
2009-11-19 16:21 957在java里面使用动态 ... -
小议偏向锁
2009-02-02 22:18 2072java SE6采用偏向锁以提高性能。 个人理解,偏向 ... -
java中调用接口及调用继承类效率区别
2009-01-19 22:34 5222都说调用接口要比调 ... -
hotsphot中的ResourceArea
2008-11-09 21:38 1370在ClassLoader::load_cla ... -
athrow程序执行代码
2008-10-10 14:38 1074看看openjdk中的athrow处理流程 { ... -
Object中notify方法
2008-10-08 10:48 2302Object.java类中notify调用的是shar ... -
Object中wait方法
2008-09-18 10:59 3700Object.wait调用 ... -
自定义类加载器loadClass
2008-09-17 15:43 1481自定义类加载器继承ClassLoader类,使用自定义类加载器 ... -
openjdk中的同步代码
2008-09-16 15:24 1871在java虚拟机中的方法同步synchroni ... -
java栈帧中的对象引用
2008-09-12 11:14 3980openjdk中的java栈帧是如何布置的呢, ... -
openjdk的周期线程
2008-09-10 10:04 1357openjdk中周期 ... -
java线程启动代码
2008-09-09 11:24 2015上次写了个《Th ... -
InterpreterRuntime::_new阅读
2008-09-05 14:52 1419InterpreterRuntime::_new为解释 ... -
java解释器的阅读
2008-09-05 10:09 1637前面已经提到了j ... -
JavaCalls::call代码阅读
2008-09-04 10:34 2878JavaCalls::call为hotspot调用j ... -
ClassFileParser::parseClassFile阅读
2008-09-02 11:29 2022instanceKlassHandle ClassF ... -
hotspot中的OO对象分析
2008-08-30 23:03 2208hotspot中的OO对象,涉 ... -
类的加载
2008-08-20 16:00 1304类通过(*env)->FindClass,也就是 ... -
Thread的调用
2008-08-19 11:03 2174在java里面创建线程new Thread().sta ... -
openJdk学习
2008-07-15 11:05 3612学习openJdk,主要 ...
相关推荐
在使用JConsole及其他性能分析工具时,也要特别注意不要频繁地手动触发垃圾回收(System.gc()),因为这可能会对应用程序性能造成负面影响,并且可能导致测试和分析结果产生偏差。 JConsole作为Java开发中的一个...
尽管模拟器无法完全模拟真实设备的行为,但它们仍然可以作为初步分析的有效工具。 3. **外部工具**:市场上存在专门针对移动设备的性能分析工具,如JProbe Mobile等,这些工具可以帮助开发者远程监控应用程序在真实...
### 并行开发入门:C#中的并行编程实践 #### 一、并行开发概述 随着计算机硬件的发展,多核处理器已经...通过以上内容的学习,可以初步掌握C#中的并行编程技巧,并能够将其应用于实际项目中,提高程序的运行效率。
#### 一、问题背景与初步探索 本文旨在探讨并解决一个常见的Java虚拟机(JVM)内存管理问题:为何JVM实际使用的最大内存容量有时会小于通过`-Xmx`参数设置的最大堆内存值。为了解决这个问题,我们首先需要理解JVM...
这对于初步的性能调试非常有用,可以在深入使用PerfView或dotnet-trace进行复杂性能分析之前,快速定位潜在问题。`dotnet-counters`提供了多个命令,如`collect`用于收集计数器数据,`list`列出可用的计数器,`...
3. **垃圾回收(GC)调优**:根据应用的特点调整GC策略,提高内存利用率。 #### 服务器配置优化 1. **增加堆内存大小**:根据应用的实际内存需求调整WAS服务器和JVM的堆内存配置。 2. **启用内存监控工具**:部署如...
System.gc()可以触发垃圾回收,但不推荐频繁使用。 16. Java框架与设计模式: Hibernate、Spring、Struts是常见的Java开发框架,用于简化开发、提高可维护性。设计模式是解决常见问题的最佳实践,如单例模式、工厂...
第一阶段涉及场景分析、需求定义、架构设计、能力开放API(包括位置信息、无线网络信息、带宽管理、应用与平台间的交互)、UE(用户设备)/APP(应用程序)的移动性管理、MEC与NFV(Network Functions ...
F2FS(Flash Friendly File System)是一种专门为固态驱动器和NAND闪存存储设备设计的文件系统,它在Linux内核版本3.8后成为了默认文件系统之一。F2FS以其良好的性能和对闪存友好的特性,如热数据和冷数据的有效分离...