Skip to main content

jdk 反汇编

· 5 min read

背景

很多时候可以通过java 命令打印反汇编信息

相关命令

jvm参数: HotSpot options (with an -XX: prefix on the command line)

核心参数是 -XX:+PrintAssembly , 这个参数可以获取对应的反汇编编码

./java   -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,*com.Hello::testIncr  com.Hello  >> test.txt

解析参数

Thread 2 "java" hit Hardware watchpoint 19: PrintAssembly

Old value = false
New value = true
JVMFlag::write<bool> (this=0x7f1814bcf140 <flagTable+17600>, value=true) at /var/jdk/src/hotspot/share/runtime/flags/jvmFlag.hpp:237
237 }
(gdb) bt
#0 JVMFlag::write<bool> (this=0x7f1814bcf140 <flagTable+17600>, value=true) at /var/jdk/src/hotspot/share/runtime/flags/jvmFlag.hpp:237
#1 0x00007f18137cf984 in TypedFlagAccessImpl<bool, EventBooleanFlagChanged>::check_constraint_and_set (this=0x7f1814bd49c0 <flag_access_bool>, flag=0x7f1814bcf140 <flagTable+17600>, value_addr=0x7f18129e7f54,
origin=JVMFlagOrigin::COMMAND_LINE, verbose=true) at /var/jdk/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp:75
#2 0x00007f18137ce655 in FlagAccessImpl_bool::set_impl (this=0x7f1814bd49c0 <flag_access_bool>, flag=0x7f1814bcf140 <flagTable+17600>, value_addr=0x7f18129e7f54, origin=JVMFlagOrigin::COMMAND_LINE)
at /var/jdk/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp:94
#3 0x00007f18137ce576 in FlagAccessImpl::set (this=0x7f1814bd49c0 <flag_access_bool>, flag=0x7f1814bcf140 <flagTable+17600>, value=0x7f18129e7f54, origin=JVMFlagOrigin::COMMAND_LINE)
at /var/jdk/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp:49
#4 0x00007f18137cc5db in JVMFlagAccess::set_impl (flag=0x7f1814bcf140 <flagTable+17600>, value=0x7f18129e7f54, origin=JVMFlagOrigin::COMMAND_LINE) at /var/jdk/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp:299
#5 0x00007f181306cdf9 in JVMFlagAccess::set<bool, 0> (flag=0x7f1814bcf140 <flagTable+17600>, value=0x7f18129e7f54, origin=JVMFlagOrigin::COMMAND_LINE) at /var/jdk/src/hotspot/share/runtime/flags/jvmFlagAccess.hpp:120
#6 0x00007f181306bd96 in JVMFlagAccess::set_bool (f=0x7f1814bcf140 <flagTable+17600>, v=0x7f18129e7f54, origin=JVMFlagOrigin::COMMAND_LINE) at /var/jdk/src/hotspot/share/runtime/flags/jvmFlagAccess.hpp:133
#7 0x00007f1813060002 in set_bool_flag (flag=0x7f1814bcf140 <flagTable+17600>, value=true, origin=JVMFlagOrigin::COMMAND_LINE) at /var/jdk/src/hotspot/share/runtime/arguments.cpp:825
#8 0x00007f18130607a9 in Arguments::parse_argument (arg=0x55dcf2d093a4 "+PrintAssembly", origin=JVMFlagOrigin::COMMAND_LINE) at /var/jdk/src/hotspot/share/runtime/arguments.cpp:993
#9 0x00007f18130611be in Arguments::process_argument (arg=0x55dcf2d093a4 "+PrintAssembly", ignore_unrecognized=0 '\000', origin=JVMFlagOrigin::COMMAND_LINE) at /var/jdk/src/hotspot/share/runtime/arguments.cpp:1179
#10 0x00007f1813066867 in Arguments::parse_each_vm_init_arg (args=0x7f18129e8d50, patch_mod_javabase=0x7f18129e87fb, origin=JVMFlagOrigin::COMMAND_LINE) at /var/jdk/src/hotspot/share/runtime/arguments.cpp:2972
#11 0x00007f18130639da in Arguments::parse_vm_init_args (vm_options_args=0x7f18129e8878, java_tool_options_args=0x7f18129e88b8, java_options_args=0x7f18129e88f8, cmd_line_args=0x7f18129e8d50)
at /var/jdk/src/hotspot/share/runtime/arguments.cpp:2174
#12 0x00007f1813068a46 in Arguments::parse (initial_cmd_args=0x7f18129e8d50) at /var/jdk/src/hotspot/share/runtime/arguments.cpp:3946
#13 0x00007f1813e5def7 in Threads::create_vm (args=0x7f18129e8d50, canTryAgain=0x7f18129e8c5b) at /var/jdk/src/hotspot/share/runtime/thread.cpp:2734
#14 0x00007f181378343b in JNI_CreateJavaVM_inner (vm=0x7f18129e8da8, penv=0x7f18129e8db0, args=0x7f18129e8d50) at /var/jdk/src/hotspot/share/prims/jni.cpp:3613
#15 0x00007f1813783787 in JNI_CreateJavaVM (vm=0x7f18129e8da8, penv=0x7f18129e8db0, args=0x7f18129e8d50) at /var/jdk/src/hotspot/share/prims/jni.cpp:3701
#16 0x00007f1814efaa6a in InitializeJVM (pvm=0x7f18129e8da8, penv=0x7f18129e8db0, ifn=0x7f18129e8e00) at /var/jdk/src/java.base/share/native/libjli/java.c:1459
#17 0x00007f1814ef75ec in JavaMain (_args=0x7ffc68186870) at /var/jdk/src/java.base/share/native/libjli/java.c:411
#18 0x00007f1814efe5ec in ThreadJavaMain (args=0x7ffc68186870) at /var/jdk/src/java.base/unix/native/libjli/java_md.c:651
#19 0x00007f1814d59b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442

堆栈:

#0  Compile::Compile (this=0x7f5eb0b5ea80, ci_env=0x7f5eb0b5f6b0, generator=0x7f5ecfee55f2 <OptoRuntime::new_instance_Type()>, 
stub_function=0x7f5ecfee3d90 <OptoRuntime::new_instance_C(Klass*, JavaThread*)> "\363\017\036\372UH\211\345H\203\354`H\211}\250H\211u\240\350[2$\377H9E\240\017\225\300\204\300t?H\215\005m\241\364",
stub_name=0x7f5ed074e78a "_new_instance_Java", is_fancy_jump=0, pass_tls=true, return_pc=false, directive=0x7f5ec822a050) at /var/jdk/src/hotspot/share/opto/compile.cpp:892
#1 0x00007f5ecfee3c98 in OptoRuntime::generate_stub (env=0x7f5eb0b5f6b0, gen=0x7f5ecfee55f2 <OptoRuntime::new_instance_Type()>,
C_function=0x7f5ecfee3d90 <OptoRuntime::new_instance_C(Klass*, JavaThread*)> "\363\017\036\372UH\211\345H\203\354`H\211}\250H\211u\240\350[2$\377H9E\240\017\225\300\204\300t?H\215\005m\241\364", name=0x7f5ed074e78a "_new_instance_Java",
is_fancy_jump=0, pass_tls=true, return_pc=false) at /var/jdk/src/hotspot/share/opto/runtime.cpp:171
#2 0x00007f5ecfee374d in OptoRuntime::generate (env=0x7f5eb0b5f6b0) at /var/jdk/src/hotspot/share/opto/runtime.cpp:139
#3 0x00007f5ecf48ab83 in C2Compiler::init_c2_runtime () at /var/jdk/src/hotspot/share/opto/c2compiler.cpp:78
#4 0x00007f5ecf48ac07 in C2Compiler::initialize (this=0x7f5ec8342980) at /var/jdk/src/hotspot/share/opto/c2compiler.cpp:91
#5 0x00007f5ecf5c2ab2 in CompileBroker::init_compiler_runtime () at /var/jdk/src/hotspot/share/compiler/compileBroker.cpp:1782
#6 0x00007f5ecf5c3046 in CompileBroker::compiler_thread_loop () at /var/jdk/src/hotspot/share/compiler/compileBroker.cpp:1919
#7 0x00007f5ecf5e5462 in CompilerThread::thread_entry (thread=0x7f5ec8343060, __the_thread__=0x7f5ec8343060) at /var/jdk/src/hotspot/share/compiler/compilerThread.cpp:59
#8 0x00007f5ed00c0009 in JavaThread::thread_main_inner (this=0x7f5ec8343060) at /var/jdk/src/hotspot/share/runtime/thread.cpp:1297
#9 0x00007f5ed00bfe92 in JavaThread::run (this=0x7f5ec8343060) at /var/jdk/src/hotspot/share/runtime/thread.cpp:1280
#10 0x00007f5ed00bd57f in Thread::call_run (this=0x7f5ec8343060) at /var/jdk/src/hotspot/share/runtime/thread.cpp:358
#11 0x00007f5ecfe041e7 in thread_native_entry (thread=0x7f5ec8343060) at /var/jdk/src/hotspot/os/linux/os_linux.cpp:705
#12 0x00007f5ed0fc0b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#13 0x00007f5ed1051bb4 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100
(gdb) b Compile::Compile
(gdb) bt
#0 nmethod::print (this=0x7fd21d591010, st=0x7fd22c000b80) at /var/jdk/src/hotspot/share/code/nmethod.cpp:2518
#1 0x00007fd23498cf10 in nmethod::decode2 (this=0x7fd21d591010, ost=0x7fd22c000b80) at /var/jdk/src/hotspot/share/code/nmethod.cpp:2887
#2 0x00007fd234985e16 in nmethod::print_nmethod (this=0x7fd21d591010, printmethod=true) at /var/jdk/src/hotspot/share/code/nmethod.cpp:962
#3 0x00007fd234985c95 in nmethod::maybe_print_nmethod (this=0x7fd21d591010, directive=0x7fd22c229f20) at /var/jdk/src/hotspot/share/code/nmethod.cpp:935
#4 0x00007fd2341a2a9e in CompileBroker::invoke_compiler_on_method (task=0x7fd22c359c10) at /var/jdk/src/hotspot/share/compiler/compileBroker.cpp:2345
#5 0x00007fd2341a12c1 in CompileBroker::compiler_thread_loop () at /var/jdk/src/hotspot/share/compiler/compileBroker.cpp:1966
#6 0x00007fd2341c3462 in CompilerThread::thread_entry (thread=0x7fd22c344ac0, __the_thread__=0x7fd22c344ac0) at /var/jdk/src/hotspot/share/compiler/compilerThread.cpp:59
#7 0x00007fd234c9e009 in JavaThread::thread_main_inner (this=0x7fd22c344ac0) at /var/jdk/src/hotspot/share/runtime/thread.cpp:1297
#8 0x00007fd234c9de92 in JavaThread::run (this=0x7fd22c344ac0) at /var/jdk/src/hotspot/share/runtime/thread.cpp:1280
#9 0x00007fd234c9b57f in Thread::call_run (this=0x7fd22c344ac0) at /var/jdk/src/hotspot/share/runtime/thread.cpp:358
#10 0x00007fd2349e21e7 in thread_native_entry (thread=0x7fd22c344ac0) at /var/jdk/src/hotspot/os/linux/os_linux.cpp:705
#11 0x00007fd235b9eb43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#12 0x00007fd235c2fbb4 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100

解析指令

(gdb) bt
#0 DirectivesStack::getMatchingDirective (method=..., comp=0x7f4b2c2bef40) at /var/jdk/src/hotspot/share/compiler/compilerDirectives.cpp:670
#1 0x00007f4b34793667 in CompileBroker::compile_method (method=..., osr_bci=-1, comp_level=3, hot_method=..., hot_count=0, compile_reason=CompileTask::Reason_MustBeCompiled, __the_thread__=0x7f4b2c02a5c0)
at /var/jdk/src/hotspot/share/compiler/compileBroker.cpp:1349
#2 0x00007f4b34770655 in CompilationPolicy::compile_if_required (m=..., __the_thread__=0x7f4b2c02a5c0) at /var/jdk/src/hotspot/share/compiler/compilationPolicy.cpp:110
#3 0x00007f4b34ae8f97 in JavaCalls::call_helper (result=0x7f4b33e21750, method=..., args=0x7f4b33e217a0, __the_thread__=0x7f4b2c02a5c0) at /var/jdk/src/hotspot/share/runtime/javaCalls.cpp:359
#4 0x00007f4b34fe0344 in os::os_exception_wrapper (f=0x7f4b34ae8ccc <JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)>, value=0x7f4b33e21750, method=..., args=0x7f4b33e217a0, thread=0x7f4b2c02a5c0)
at /var/jdk/src/hotspot/os/linux/os_linux.cpp:4794
#5 0x00007f4b34ae8cc9 in JavaCalls::call (result=0x7f4b33e21750, method=..., args=0x7f4b33e217a0, __the_thread__=0x7f4b2c02a5c0) at /var/jdk/src/hotspot/share/runtime/javaCalls.cpp:330
#6 0x00007f4b34ab6626 in InstanceKlass::call_class_initializer (this=0x80004c5e8, __the_thread__=0x7f4b2c02a5c0) at /var/jdk/src/hotspot/share/oops/instanceKlass.cpp:1519
#7 0x00007f4b34ab50aa in InstanceKlass::initialize_impl (this=0x80004c5e8, __the_thread__=0x7f4b2c02a5c0) at /var/jdk/src/hotspot/share/oops/instanceKlass.cpp:1177
#8 0x00007f4b34ab3adc in InstanceKlass::initialize (this=0x80004c5e8, __the_thread__=0x7f4b2c02a5c0) at /var/jdk/src/hotspot/share/oops/instanceKlass.cpp:796
#9 0x00007f4b352905de in initialize_class (class_name=0x7f4b3114d470, __the_thread__=0x7f4b2c02a5c0) at /var/jdk/src/hotspot/share/runtime/thread.cpp:689
#10 0x00007f4b35296d82 in Threads::initialize_jsr292_core_classes (__the_thread__=0x7f4b2c02a5c0) at /var/jdk/src/hotspot/share/runtime/thread.cpp:2687
#11 0x00007f4b352975e0 in Threads::create_vm (args=0x7f4b33e21d50, canTryAgain=0x7f4b33e21c5b) at /var/jdk/src/hotspot/share/runtime/thread.cpp:2987
#12 0x00007f4b34bbc43b in JNI_CreateJavaVM_inner (vm=0x7f4b33e21da8, penv=0x7f4b33e21db0, args=0x7f4b33e21d50) at /var/jdk/src/hotspot/share/prims/jni.cpp:3613
#13 0x00007f4b34bbc787 in JNI_CreateJavaVM (vm=0x7f4b33e21da8, penv=0x7f4b33e21db0, args=0x7f4b33e21d50) at /var/jdk/src/hotspot/share/prims/jni.cpp:3701
#14 0x00007f4b36333a6a in InitializeJVM (pvm=0x7f4b33e21da8, penv=0x7f4b33e21db0, ifn=0x7f4b33e21e00) at /var/jdk/src/java.base/share/native/libjli/java.c:1459
#15 0x00007f4b363305ec in JavaMain (_args=0x7fff1f7dd300) at /var/jdk/src/java.base/share/native/libjli/java.c:411
#16 0x00007f4b363375ec in ThreadJavaMain (args=0x7fff1f7dd300) at /var/jdk/src/java.base/unix/native/libjli/java_md.c:651
#17 0x00007f4b36192b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#18 0x00007f4b36223bb4 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100

输出结果

输出结果:


------------------------ OptoAssembly for Compile_id = 26 -----------------------
#
# void ( )
#
# -- Old rsp -- Framesize: 32 --
#r591 rsp+28: in_preserve
#r590 rsp+24: return address
#r589 rsp+20: in_preserve
#r588 rsp+16: saved fp register
#r587 rsp+12: pad2, stack alignment
#r586 rsp+ 8: pad2, stack alignment
#r585 rsp+ 4: Fixed slot 1
#r584 rsp+ 0: Fixed slot 0
#
000 N1: # out( B1 ) <- in( B1 ) Freq: 1

000 B1: # out( N1 ) <- BLOCK HEAD IS JUNK Freq: 1
000 # stack bang (96 bytes)
pushq rbp # Save rbp
subq rsp, #16 # Create frame

00c movq R10, java/lang/Class:exact * # ptr
016 movl R8, [R10 + #112 (8-bit)] # int ! Field: volatile com/Hello.i
01a MEMBAR-acquire ! (empty encoding)
01a MEMBAR-release ! (empty encoding)
01a incl R8 # int
01d movl [R10 + #112 (8-bit)], R8 # int ! Field: volatile com/Hello.i
021 lock addl [rsp + #0], 0 ! membar_volatile
027 addq rsp, 16 # Destroy frame
popq rbp
cmpq rsp, poll_offset[r15_thread]
ja #safepoint_stub # Safepoint: poll for GC

039 ret

相关指令:

// jdk 中的函数输出上面的汇编
PhaseOutput::dump_asm_on

相关阅读

zookeeper connetion loss

· One min read

背景

returned error: Code: 999, e.displayText() = DB::Exception: Cannot allocate block number in ZooKeeper: Coordination::Exception: Connection loss, path: xxx

场景

最近偶尔发生clickhouse发生链接丢失的情况

cpp_flag

· One min read

背景

编译c++ 时候需要了解编译过程

cmake 添加c++ flag

当我们用g++编译一个程序的时候,经常会有些警告或者error。这时候,会弹出对应的警告和error,举例:

error: unused variable 'productSize' [-Werror,-Wunused-variable]

你会看到-Werror,-Wunused-variable , 意思是因为这个选项导致error,其实是我有定义了但是没有使用的变量。

如果我们想关闭,可以添加-Wno-unused-variable 也就是在原来的报错的-W-xxx 改成-Wno-xxx 即可

我们可以在add_compile_options 添加对应的编译flag

    add_compile_options(-Wall -Wextra -pedantic -Werror  -Wno-unused-variable)

jdk 堆栈

· One min read

背景

想了解jdk的的实现和php有什么不一样。

堆栈

jdk 会将opcode 生成对应的汇编代码,生成汇编的代码如下:

(gdb) where
#0 AbstractAssembler::emit_int8 (this=0x7ffff00198a0, x=-64 '\300') at /home/ubuntu/jdk/src/hotspot/share/asm/assembler.hpp:286
#1 0x00007ffff62513e9 in Assembler::emit_arith (this=0x7ffff00198a0, op1=133, op2=192, dst=0x0, src=0x0) at /home/ubuntu/jdk/src/hotspot/cpu/x86/assembler_x86.cpp:300
#2 0x00007ffff6284cf3 in Assembler::testq (this=0x7ffff00198a0, dst=0x0, src=0x0) at /home/ubuntu/jdk/src/hotspot/cpu/x86/assembler_x86.cpp:9191
#3 0x00007ffff6bcd75b in MacroAssembler::testptr (this=0x7ffff00198a0, dst=0x0, src=0x0) at /home/ubuntu/jdk/src/hotspot/cpu/x86/macroAssembler_x86.cpp:4072
#4 0x00007ffff6f5b67f in StubGenerator::generate_forward_exception (this=0x7ffff5b68890) at /home/ubuntu/jdk/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp:537
#5 0x00007ffff6f7dd2a in StubGenerator::generate_initial (this=0x7ffff5b68890) at /home/ubuntu/jdk/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp:5752
#6 0x00007ffff6f7e9db in StubGenerator::StubGenerator (this=0x7ffff5b68890, code=0x7ffff5b68940, all=false)
at /home/ubuntu/jdk/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp:5994
#7 0x00007ffff6f589d3 in StubGenerator_generate (code=0x7ffff5b68940, all=false) at /home/ubuntu/jdk/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp:6000
#8 0x00007ffff6f7eae9 in StubRoutines::initialize1 () at /home/ubuntu/jdk/src/hotspot/share/runtime/stubRoutines.cpp:195
#9 0x00007ffff6f7fb77 in stubRoutines_init1 () at /home/ubuntu/jdk/src/hotspot/share/runtime/stubRoutines.cpp:374
#10 0x00007ffff686a610 in init_globals () at /home/ubuntu/jdk/src/hotspot/share/runtime/init.cpp:112
#11 0x00007ffff700e2fd in Threads::create_vm (args=0x7ffff5b68e20, canTryAgain=0x7ffff5b68d2b) at /home/ubuntu/jdk/src/hotspot/share/runtime/thread.cpp:3729
#12 0x00007ffff697a82d in JNI_CreateJavaVM_inner (vm=0x7ffff5b68e78, penv=0x7ffff5b68e80, args=0x7ffff5b68e20) at /home/ubuntu/jdk/src/hotspot/share/prims/jni.cpp:3935
#13 0x00007ffff697ab47 in JNI_CreateJavaVM (vm=0x7ffff5b68e78, penv=0x7ffff5b68e80, args=0x7ffff5b68e20) at /home/ubuntu/jdk/src/hotspot/share/prims/jni.cpp:4021
#14 0x00007ffff7fba8a2 in InitializeJVM (pvm=0x7ffff5b68e78, penv=0x7ffff5b68e80, ifn=0x7ffff5b68ed0) at /home/ubuntu/jdk/src/java.base/share/native/libjli/java.c:1529
#15 0x00007ffff7fb7453 in JavaMain (_args=0x7ffffffface0) at /home/ubuntu/jdk/src/java.base/share/native/libjli/java.c:414
#16 0x00007ffff7d79609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#17 0x00007ffff7ed5163 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

jdk编译

· 2 min read

第一步

拉取代码

git clone https://github.com/openjdk/jdk.git  

第二步

本地版本:

我本地的jdk版本是17

java -version
openjdk version "17.0.4" 2022-07-19

jdk 只能由上一个版本自举,所以必须要切到下一个大版本 ,我本地是jdk17 ,所以要切到jdk 18

## 切换到jdk18
git checkout jdk-18+37

## 生成makefile

./configure --with-debug-level=slowdebug --with-extra-cflags="-Wno-nonnull -Wno-maybe-uninitialized -Wno-free-nonheap-object"
## 2个线程同时编译

make JOBS=2 CONF=linux-x86_64-server-slowdebug

相关错误

onfigure: error: Could not find all X11 headers (shape.h Xrender.h Xrandr.h XTest.h Intrinsic.h). You might be able to fix this by running 'sudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev'.
configure exiting with result code 1

解决方案:

sudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev
configure: error: Could not find cups! You might be able to fix this by running 'sudo apt-get install libcups2-dev'. 
configure exiting with result code 1

解决方案:

sudo apt-get install libcups2-dev

相关阅读

java thread local 初始化时机

· 3 min read

背景

java 的spring boot 不少地方用到了利用java 的thread local map 来实现线程变量隔离。 想要理解java的相关内容。

实现

核心就在于每次创建线程的对象实例的时候,在线程的初始化时候会把threadlocal map 创建好 , 每个线程一个自己的map , 从而实现线程隔离

文件路径在jdk 的这里 src/java.base/share/classes/java/lang/Thread.java

   /**
* Initializes a virtual Thread.
*
* @param name thread name, can be null
* @param characteristics thread characteristics
* @param bound true when bound to an OS thread
*/
Thread(String name, int characteristics, boolean bound) {
...
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parentMap);
...
}

threadlocal 初始化

threadlocal 有多个入口 ,最后都是通过createMap 初始化ThreadlocalMap , 这个map 由Thread 的实例化对象持有,

核心对象成员: threadLocals . 每个线程自己持有一个map , 这个map的entry是一个weakreference

    /* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
    /**
* Sets the current thread's copy of this thread-local variable
* to the specified value. Most subclasses will have no need to
* override this method, relying solely on the {@link #initialValue}
* method to set the values of thread-locals.
*
* @param value the value to be stored in the current thread's copy of
* this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value);
} else {
createMap(t, value); // 初始化
}
}
    /**
* Variant of set() to establish initialValue. Used instead
* of set() in case user has overridden the set() method.
*
* @return the initial value
*/
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value);
} else {
createMap(t, value); // 初始化
}
if (this instanceof TerminatingThreadLocal) {
TerminatingThreadLocal.register((TerminatingThreadLocal<?>) this);
}
return value;

每个thread 持有一个threadLocals 对象

    /**
* Get the map associated with a ThreadLocal. Overridden in
* InheritableThreadLocal.
*
* @param t the current thread
* @return the map
*/
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}

相关阅读

httpServerletRequest autowired 原因

· One min read

背景

autowired 默认都是一般都是单例,为什么httpServerletRequest是做到不是单例呢?

堆栈:

getRequestAttributes:105, RequestContextHolder (org.springframework.web.context.request)
processRequest:997, FrameworkServlet (org.springframework.web.servlet)
doPost:909, FrameworkServlet (org.springframework.web.servlet)
service:652, HttpServlet (javax.servlet.http)
service:883, FrameworkServlet (org.springframework.web.servlet)
service:733, HttpServlet (javax.servlet.http)
internalDoFilter:227, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilter:53, WsFilter (org.apache.tomcat.websocket.server)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:100, RequestContextFilter (org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:93, FormContentFilter (org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:97, WebMvcMetricsFilter (org.springframework.boot.actuate.metrics.web.servlet)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:201, CharacterEncodingFilter (org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
invoke:202, StandardWrapperValve (org.apache.catalina.core)
invoke:97, StandardContextValve (org.apache.catalina.core)
invoke:542, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:143, StandardHostValve (org.apache.catalina.core)
invoke:92, ErrorReportValve (org.apache.catalina.valves)
invoke:78, StandardEngineValve (org.apache.catalina.core)
service:357, CoyoteAdapter (org.apache.catalina.connector)
service:374, Http11Processor (org.apache.coyote.http11)
process:65, AbstractProcessorLight (org.apache.coyote)
process:893, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1707, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1128, ThreadPoolExecutor (java.util.concurrent)
run:628, ThreadPoolExecutor$Worker (java.util.concurrent)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:834, Thread (java.lang)

相关阅读

priority queue

· 2 min read

lucene 搜索的结果搜索经过soccer算出分数之后,还需要topK取前几个数据,所以需要使用到topk的算法。 一般用优先队列实现。

介绍

下面都是描述最大优先队列

优先队列分为两个,一个是最小优先,一个是最大优先。其实就是方向改变而已。

我们先介绍他的性质:

组成 : 优先队列是item集合S 。每个item 包含两个内容:element 和key

操作

  • insert(S , item)
  • maxnum(S)
  • extract_max(S)
  • increase_key (S,element,key) 将优先队列里面

证明

对于一个非空满二叉树,第一个节点编号是index=1 则对每个节点index :

  • 他的左节点left=index *2
  • right = index *2 +1

证明: 归纳法 init: 当index= 1 时, left = 2 , 满足left = index*2
当index=1 时,right = 3 , 满足 right = index*2 +1

deduction: n+1 元素: 如果他是左节点 , 则他的前一个节点满足 n = (pre_parent *2 +1) 对于n+1 个元素 , n+1 = (pre_parent *2 +1) +1 = (pre_parent +1 )*2 即满足递推公式

同理右节点同理

所以证明完毕

相关论文

算法导论

Method Reference Expressions

· One min read

背景

了解java 的method reference

介绍

java method reference 在上述文档的:15.13 Method Reference Expressions 这一个小节有介绍

java method reference 是java的一个表达式, 表达式经过求值,会得到一个对象. 那么method reference结果是一个functional interface type

Evaluation of a method reference expression produces an instance of a functional
interface type