- 浏览: 100283 次
- 性别:
- 来自: 武汉
最新评论
-
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 898在java里面使用动态 ... -
小议偏向锁
2009-02-02 22:18 1970java SE6采用偏向锁以提高性能。 个人理解,偏向 ... -
java中调用接口及调用继承类效率区别
2009-01-19 22:34 5102都说调用接口要比调 ... -
hotsphot中的ResourceArea
2008-11-09 21:38 1299在ClassLoader::load_cla ... -
athrow程序执行代码
2008-10-10 14:38 998看看openjdk中的athrow处理流程 { ... -
Object中notify方法
2008-10-08 10:48 2229Object.java类中notify调用的是shar ... -
Object中wait方法
2008-09-18 10:59 3598Object.wait调用 ... -
自定义类加载器loadClass
2008-09-17 15:43 1414自定义类加载器继承ClassLoader类,使用自定义类加载器 ... -
openjdk中的同步代码
2008-09-16 15:24 1726在java虚拟机中的方法同步synchroni ... -
java栈帧中的对象引用
2008-09-12 11:14 3908openjdk中的java栈帧是如何布置的呢, ... -
openjdk的周期线程
2008-09-10 10:04 1287openjdk中周期 ... -
java线程启动代码
2008-09-09 11:24 1954上次写了个《Th ... -
InterpreterRuntime::_new阅读
2008-09-05 14:52 1315InterpreterRuntime::_new为解释 ... -
java解释器的阅读
2008-09-05 10:09 1590前面已经提到了j ... -
JavaCalls::call代码阅读
2008-09-04 10:34 2791JavaCalls::call为hotspot调用j ... -
ClassFileParser::parseClassFile阅读
2008-09-02 11:29 1929instanceKlassHandle ClassF ... -
hotspot中的OO对象分析
2008-08-30 23:03 2146hotspot中的OO对象,涉 ... -
类的加载
2008-08-20 16:00 1242类通过(*env)->FindClass,也就是 ... -
Thread的调用
2008-08-19 11:03 2087在java里面创建线程new Thread().sta ... -
openJdk学习
2008-07-15 11:05 3537学习openJdk,主要 ...
相关推荐
SRE 每天都处理生产环境中出现的各种各样的问题,有些问题很具有代表性,这次我们将分享与Java语言中System.gc()相关的两个典型案例,介绍如何分析这种问题,并且如何定位且修复这些问题。
可用附件中的simg2img.exe来转化一下原始的system.img,然后再用其中的ext2Explorer来浏览提取system.img中的内容。 用法:1、将system.img改名为system.img.ext4。2、命令行cd到simg2img.exe目录下,执行命令“simg...
现在的第三方安卓8.1rom里面的system.new.dat.br,怎么转成原来的system.new.dat 2015年9月, Google就已经在官方博客上发布了新的压缩算法Brotli, 并开源在了Github上.同时还发布了一个研究报告, 対Brotli, ...
<data name="9" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\9.jpg;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11...
System.Runtime.Serialization.dll System.Runtime.Serialization.dll System.Runtime.Serialization.dll
支持解压Android 8.1~9.0新增的br格式刷机包,同时继承了dat解包工具,方便同时解压system.new.dat文件
许多朋友下载Ajax源码后无法运行,需要System.Web.Extensions.dll和System.Web.Extensions.Design.dll 这2个DLL文件,发给需要的朋友!
system.new.dat与system.new.dat.br互转工具
System.Windows.Forms.TreeListView.dll
ADO.NET Data Provider for SQLite(->net2.0,net4.0,net4.5,net4.51,net4.6,netstandard2.0),System.Data.SQLite.1.0.111.0,System.Data.SQLite.Core.1.0.111.0,System.Data.SQLite.EF6.1.0.111.0,System.Data....
.net sqlite_1.0.76.0里面包括: System.Data.SQLite.dll System.Data.SQLite.dll类库文档 sqlite-doc-3070800文档
把unyaffs与system.img放到同一目录,进入命令模式,运行:unyaffs system.img;windows上的android img解包工具,用于解system.img等文件,不包含打包功能。
System.Runtime.Serialization.DLL
主要介绍了Android垃圾回收机制及程序优化System.gc的相关资料,需要的朋友可以参考下
然后mkyaffs2image system system.img打包生成新的system.img,替换原来的system.img,并启动模拟器,效果图如下: 修改代码: 工具:odextools(参考:《一键odex批量合并工具odextools的重新整理与使用...
SYSTEM.NEW.DAT解包工具,解包工具,安卓SYSTEM.NEW.DAT解包工具
支持system.new.dat与system.new.dat.br互相转换功能,同样也支持vendor.new.dat与vendor.new.dat.br互相转换,操作十分简单,只需一键就能转换。也支持img与dat一键互换,安卓全版本适配。
.Net 3.5 下使用的 System.Threading.Tasks。 安装完成后,添加引用时只需要在安装目录 C:\Program Files (x86)\Microsoft Reactive Extensions\Redist\DesktopV2 下找到 System.Threading.dll,添加即可
C#System.Drawing.dll,导入unityPlugins文件下,system.drawing.dll文件下载,解决找不到system.drawing.dll的问题
在官网下载的sqlite最新System.Data.Sqlite.dll,如果我们在C#中调用sqlite遇到错误System.BadImageFormatException:“未能加载文件或程序集“System.Data.SQLite, Version=1.0.60.0, Culture=neutral,那么有可能是...