Skip to main content

100 posts tagged with "java"

View All Tags

java sort default order

· 2 min read

背景

java 的Array.sort()或者.stream.sorted() 都会使用Comparable<T> 作为参数
目前需要了解这些排序函数究竟是升序还是降序的

一句话答案

所有的排序都是升序的ascending

原因

Array.sort() , .stream.sorted() 都使用Comparable<T>这个类,都需要实现接口int compare(T o1, T o2);

我们看看接口compare的注释:

Params:
o1 – the first object to be compared. o2 – the second object to be compared.
Returns:
a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
int compare(T o1, T o2);

入参有两个:第一个参数o1,第二个是o2 返回值:

  • 如果o1 < o2 返回 负数
  • 如果o1 > o2 返回正数
  • 如果o1 = o2,返回0

再看看注释java.util.Comparator<T> , 默认都是natural ordering

    /**
* Returns a comparator that imposes the reverse of the <em>natural
* ordering</em>.
*
* <p>The returned comparator is serializable and throws {@link
* NullPointerException} when comparing {@code null}.
*
* @param <T> the {@link Comparable} type of element to be compared
* @return a comparator that imposes the reverse of the <i>natural
* ordering</i> on {@code Comparable} objects.
* @see Comparable
* @since 1.8
*/
public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
return Collections.reverseOrder();
}


相关阅读

自然排序说明 stackoverflow

Payload value must not be empty

· 3 min read

背景

生产环境rabbitmq遇到错误:Payload value must not be empty

Caused by: org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException: Could not resolve method parameter at index 0 in public void com.xxxx.consume(java.lang.String,org.springframework.amqp.core.Message,com.rabbitmq.client.Channel) throws java.lang.Exception: 1 error(s): [Error in object 'content': codes []; arguments []; default message [Payload value must not be empty]] 
at org.springframework.messaging.handler.annotation.support.PayloadMethodArgumentResolver.resolveArgument(PayloadMethodArgumentResolver.java:122)
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:117)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:147)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:115)
at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:75)
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:261)

解决方式

添加注解@Payload

    @RabbitListener(queues = "queue")
public void consume( @Payload(required = false) String content, Message message, Channel channel) throws Exception { // 将@Payload 塞到 content 字段
...
}

查看源码

扒了一下代码查看原因: 路径

  • org\springframework\messaging\handler\annotation\support\PayloadMethodArgumentResolver.java
	public Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception {
Payload ann = parameter.getParameterAnnotation(Payload.class);
if (ann != null && StringUtils.hasText(ann.expression())) {
throw new IllegalStateException("@Payload SpEL expressions not supported by this resolver");
}

Object payload = message.getPayload();
if (isEmptyPayload(payload)) { // 条件1
if (ann == null || ann.required()) { // 条件2
String paramName = getParameterName(parameter);
BindingResult bindingResult = new BeanPropertyBindingResult(payload, paramName);
bindingResult.addError(new ObjectError(paramName, "Payload value must not be empty")); // 在这里会校验空
throw new MethodArgumentNotValidException(message, parameter, bindingResult);
}
else {
return null;
}
}
}
  • 条件1 : payload 是空
  • 条件2 : 没有@Payload 注解或者 @Payload(required = ture)

原因: 满足条件1和条件2就会抛出异常

默认不加注解的时候会满足条件1和2 , 所以解决方案: 添加注解@Payload

    @RabbitListener(queues = "queue")
public void consume( @Payload(required = false) String content, Message message, Channel channel) throws Exception { // 将@Payload 塞到 content 字段
...
}

堆栈

resolveArgument:111, PayloadMethodArgumentResolver (org.springframework.messaging.handler.annotation.support)
resolveArgument:117, HandlerMethodArgumentResolverComposite (org.springframework.messaging.handler.invocation)
getMethodArgumentValues:147, InvocableHandlerMethod (org.springframework.messaging.handler.invocation)
invoke:115, InvocableHandlerMethod (org.springframework.messaging.handler.invocation)
invoke:75, HandlerAdapter (org.springframework.amqp.rabbit.listener.adapter)
invokeHandler:261, MessagingMessageListenerAdapter (org.springframework.amqp.rabbit.listener.adapter)
invokeHandlerAndProcessResult:207, MessagingMessageListenerAdapter (org.springframework.amqp.rabbit.listener.adapter)
onMessage:146, MessagingMessageListenerAdapter (org.springframework.amqp.rabbit.listener.adapter)
doInvokeListener:1665, AbstractMessageListenerContainer (org.springframework.amqp.rabbit.listener)
actualInvokeListener:1584, AbstractMessageListenerContainer (org.springframework.amqp.rabbit.listener)
invokeListener:-1, 1393414871 (org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer$$Lambda$1549)
invoke0:-1, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:62, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:43, DelegatingMethodAccessorImpl (jdk.internal.reflect)
invoke:566, Method (java.lang.reflect)
invokeJoinpointUsingReflection:344, AopUtils (org.springframework.aop.support)
invokeJoinpoint:198, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:163, ReflectiveMethodInvocation (org.springframework.aop.framework)
doWithRetry:93, RetryOperationsInterceptor$1 (org.springframework.retry.interceptor)
doExecute:329, RetryTemplate (org.springframework.retry.support)
execute:225, RetryTemplate (org.springframework.retry.support)
invoke:116, RetryOperationsInterceptor (org.springframework.retry.interceptor)
proceed:186, ReflectiveMethodInvocation (org.springframework.aop.framework)
invoke:215, JdkDynamicAopProxy (org.springframework.aop.framework)
invokeListener:-1, $Proxy247 (org.springframework.amqp.rabbit.listener)
invokeListener:1572, AbstractMessageListenerContainer (org.springframework.amqp.rabbit.listener)
doExecuteListener:1563, AbstractMessageListenerContainer (org.springframework.amqp.rabbit.listener)
executeListener:1507, AbstractMessageListenerContainer (org.springframework.amqp.rabbit.listener)
doReceiveAndExecute:967, SimpleMessageListenerContainer (org.springframework.amqp.rabbit.listener)
receiveAndExecute:914, SimpleMessageListenerContainer (org.springframework.amqp.rabbit.listener)
access$1600:83, SimpleMessageListenerContainer (org.springframework.amqp.rabbit.listener)
mainLoop:1291, SimpleMessageListenerContainer$AsyncMessageProcessingConsumer (org.springframework.amqp.rabbit.listener)
run:1197, SimpleMessageListenerContainer$AsyncMessageProcessingConsumer (org.springframework.amqp.rabbit.listener)
run:834, Thread (java.lang)

java 线程池

· One min read

背景

了解java源码包里面线程池的细节

线程池

线程池是管理一堆线程的对象。对于线程池来说,不同线程池主要是他们创建、调度、销毁的的各种策略的不一样

基础类

Executors

executor/executors/executorService:

executor 是一个接口,类似Runable , 实际上也是差不多功能

public interface Executor {
void execute(Runnable var1);
}

fst 结构

· 6 min read

背景

了解lucene 的fst结构

核心函数

freeezeTail -> compileNode

  private void freezeTail(int prefixLenPlus1) throws IOException {  // 入参是一个偏移值:  公共前缀+ 1
final int downTo = Math.max(1, prefixLenPlus1);
for (int idx = lastInput.length(); idx >= downTo; idx--) {

boolean doPrune = false;
boolean doCompile = false;


if (doCompile) {
...
parent.replaceLast(
lastInput.intAt(idx - 1),
compileNode(node, 1 + lastInput.length() - idx),
nextFinalOutput,
isFinal);
...
}
}
}
}
  private CompiledNode compileNode(UnCompiledNode<T> nodeIn, int tailLength) throws IOException {
final long node;
long bytesPosStart = bytes.getPosition();
if (dedupHash != null
&& (doShareNonSingletonNodes || nodeIn.numArcs <= 1)
&& tailLength <= shareMaxTailLength) {
if (nodeIn.numArcs == 0) {
node = fst.addNode(this, nodeIn);
lastFrozenNode = node;
} else {
node = dedupHash.add(this, nodeIn);
}
} else {
node = fst.addNode(this, nodeIn);
}
assert node != -2;

long bytesPosEnd = bytes.getPosition();
if (bytesPosEnd != bytesPosStart) {
// The FST added a new node:
assert bytesPosEnd > bytesPosStart;
lastFrozenNode = node;
}

nodeIn.clear();

final CompiledNode fn = new CompiledNode();
fn.node = node;
return fn;
}
  // serializes new node by appending its bytes to the end
// of the current byte[]
long addNode(FSTCompiler<T> fstCompiler, FSTCompiler.UnCompiledNode<T> nodeIn)
throws IOException {
T NO_OUTPUT = outputs.getNoOutput();

// System.out.println("FST.addNode pos=" + bytes.getPosition() + " numArcs=" + nodeIn.numArcs);
if (nodeIn.numArcs == 0) {
if (nodeIn.isFinal) {
return FINAL_END_NODE;
} else {
return NON_FINAL_END_NODE;
}
}
final long startAddress = fstCompiler.bytes.getPosition();
// System.out.println(" startAddr=" + startAddress);

final boolean doFixedLengthArcs = shouldExpandNodeWithFixedLengthArcs(fstCompiler, nodeIn);
if (doFixedLengthArcs) {
// System.out.println(" fixed length arcs");
if (fstCompiler.numBytesPerArc.length < nodeIn.numArcs) {
fstCompiler.numBytesPerArc = new int[ArrayUtil.oversize(nodeIn.numArcs, Integer.BYTES)];
fstCompiler.numLabelBytesPerArc = new int[fstCompiler.numBytesPerArc.length];
}
}

fstCompiler.arcCount += nodeIn.numArcs;

final int lastArc = nodeIn.numArcs - 1;

long lastArcStart = fstCompiler.bytes.getPosition();
int maxBytesPerArc = 0;
int maxBytesPerArcWithoutLabel = 0;
for (int arcIdx = 0; arcIdx < nodeIn.numArcs; arcIdx++) {
final FSTCompiler.Arc<T> arc = nodeIn.arcs[arcIdx];
final FSTCompiler.CompiledNode target = (FSTCompiler.CompiledNode) arc.target;
int flags = 0;
// System.out.println(" arc " + arcIdx + " label=" + arc.label + " -> target=" +
// target.node);

if (arcIdx == lastArc) {
flags += BIT_LAST_ARC;
}

if (fstCompiler.lastFrozenNode == target.node && !doFixedLengthArcs) {
// TODO: for better perf (but more RAM used) we
// could avoid this except when arc is "near" the
// last arc:
flags += BIT_TARGET_NEXT;
}

if (arc.isFinal) {
flags += BIT_FINAL_ARC;
if (arc.nextFinalOutput != NO_OUTPUT) {
flags += BIT_ARC_HAS_FINAL_OUTPUT;
}
} else {
assert arc.nextFinalOutput == NO_OUTPUT;
}

boolean targetHasArcs = target.node > 0;

if (!targetHasArcs) {
flags += BIT_STOP_NODE;
}

if (arc.output != NO_OUTPUT) {
flags += BIT_ARC_HAS_OUTPUT;
}

fstCompiler.bytes.writeByte((byte) flags);
long labelStart = fstCompiler.bytes.getPosition();
writeLabel(fstCompiler.bytes, arc.label);
int numLabelBytes = (int) (fstCompiler.bytes.getPosition() - labelStart);

// System.out.println(" write arc: label=" + (char) arc.label + " flags=" + flags + "
// target=" + target.node + " pos=" + bytes.getPosition() + " output=" +
// outputs.outputToString(arc.output));

if (arc.output != NO_OUTPUT) {
outputs.write(arc.output, fstCompiler.bytes);
// System.out.println(" write output");
}

if (arc.nextFinalOutput != NO_OUTPUT) {
// System.out.println(" write final output");
outputs.writeFinalOutput(arc.nextFinalOutput, fstCompiler.bytes);
}

if (targetHasArcs && (flags & BIT_TARGET_NEXT) == 0) {
assert target.node > 0;
// System.out.println(" write target");
fstCompiler.bytes.writeVLong(target.node);
}

// just write the arcs "like normal" on first pass, but record how many bytes each one took
// and max byte size:
if (doFixedLengthArcs) {
int numArcBytes = (int) (fstCompiler.bytes.getPosition() - lastArcStart);
fstCompiler.numBytesPerArc[arcIdx] = numArcBytes;
fstCompiler.numLabelBytesPerArc[arcIdx] = numLabelBytes;
lastArcStart = fstCompiler.bytes.getPosition();
maxBytesPerArc = Math.max(maxBytesPerArc, numArcBytes);
maxBytesPerArcWithoutLabel =
Math.max(maxBytesPerArcWithoutLabel, numArcBytes - numLabelBytes);
// System.out.println(" arcBytes=" + numArcBytes + " labelBytes=" + numLabelBytes);
}
}

// TODO: try to avoid wasteful cases: disable doFixedLengthArcs in that case
/*
*
* LUCENE-4682: what is a fair heuristic here?
* It could involve some of these:
* 1. how "busy" the node is: nodeIn.inputCount relative to frontier[0].inputCount?
* 2. how much binSearch saves over scan: nodeIn.numArcs
* 3. waste: numBytes vs numBytesExpanded
*
* the one below just looks at #3
if (doFixedLengthArcs) {
// rough heuristic: make this 1.25 "waste factor" a parameter to the phd ctor????
int numBytes = lastArcStart - startAddress;
int numBytesExpanded = maxBytesPerArc * nodeIn.numArcs;
if (numBytesExpanded > numBytes*1.25) {
doFixedLengthArcs = false;
}
}
*/

if (doFixedLengthArcs) {
assert maxBytesPerArc > 0;
// 2nd pass just "expands" all arcs to take up a fixed byte size

int labelRange = nodeIn.arcs[nodeIn.numArcs - 1].label - nodeIn.arcs[0].label + 1;
assert labelRange > 0;
if (shouldExpandNodeWithDirectAddressing(
fstCompiler, nodeIn, maxBytesPerArc, maxBytesPerArcWithoutLabel, labelRange)) {
writeNodeForDirectAddressing(
fstCompiler, nodeIn, startAddress, maxBytesPerArcWithoutLabel, labelRange);
fstCompiler.directAddressingNodeCount++;
} else {
writeNodeForBinarySearch(fstCompiler, nodeIn, startAddress, maxBytesPerArc);
fstCompiler.binarySearchNodeCount++;
}
}

final long thisNodeAddress = fstCompiler.bytes.getPosition() - 1;
fstCompiler.bytes.reverse(startAddress, thisNodeAddress);
fstCompiler.nodeCount++;
return thisNodeAddress;
}

Arc<T> 描述的是一个弧

//package org.apache.lucene.util.fst;
// org\apache\lucene\util\fst\FSTCompiler.java
/** Expert: holds a pending (seen but not yet serialized) arc. */
static class Arc<T> {
int label; // really an "unsigned" byte // 一个label
Node target; // 举例:a -> b 那么target 就是b
boolean isFinal;
T output;
T nextFinalOutput;
}

例子

cat的权重是5
dog的权重是7
dogs的权重是13

   String inputValues[] = {"cat", "dog", "dogs"};
long[] outputValues = {5, 7, 13};

下面是一个cat的例子 cat包含三个字符c,a ,t,分别代表三个ASCII码:

  • c:99
  • a:97
  • t:116

定义Arc: 一个弧包含三个内容: [a:label1]->[b:label2] 来描述一个弧:a指向b .其中a的值是label1, b的值是label2

下面是idea的截图, [2747:c] -> [2856:a] -> [2860:t]

fst linklist

下面是fst.bytes 的例子

fst bytes

最后是变成下列格式:

[0, 116, 15, 97, 6, 6, 115, 31, 103, 7, 111, 6, 7, 100, 22, 4, 5, 99, 16]

相关阅读

java 数组声明位置区别

· One min read

背景

  String inputValues[] = {"cat", "dog", "dogs"};

当我声明一个数组,方括号在右边的时候, idea会有个很小警告:

C-style array declaration of local variable 'inputValues' 

IDE劝我改成

  String[] inputValues = {"cat", "dog", "dogs"};

那么他们有什么区别呢?

我查了stackoverflow

这两个是等价的

jls是如何定义的?

相关引用

volatile java 实现

· 17 min read

背景

了解java volatile实现

实现

核心在这里: is_volatile_shift

void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
transition(vtos, vtos);

const Register cache = rcx;
const Register index = rdx;
const Register obj = rcx;
const Register off = rbx;
const Register flags = rax;

resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
jvmti_post_field_mod(cache, index, is_static);
load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);

Label notVolatile, Done;
__ movl(rdx, flags);
__ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift); // 右移volatile 标志位 , 然后如果是volatile ,则走到不太分支
__ andl(rdx, 0x1);

// Check for volatile store
__ testl(rdx, rdx);
__ jcc(Assembler::zero, notVolatile);

putfield_or_static_helper(byte_no, is_static, rc, obj, off, flags);
volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
Assembler::StoreStore));
__ jmp(Done);
__ bind(notVolatile);

putfield_or_static_helper(byte_no, is_static, rc, obj, off, flags);

__ bind(Done);
}

这是具体的代码:

// ----------------------------------------------------------------------------
// Volatile variables demand their effects be made known to all CPU's
// in order. Store buffers on most chips allow reads & writes to
// reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode
// without some kind of memory barrier (i.e., it's not sufficient that
// the interpreter does not reorder volatile references, the hardware
// also must not reorder them).
//
// According to the new Java Memory Model (JMM):
// (1) All volatiles are serialized wrt to each other. ALSO reads &
// writes act as aquire & release, so:
// (2) A read cannot let unrelated NON-volatile memory refs that
// happen after the read float up to before the read. It's OK for
// non-volatile memory refs that happen before the volatile read to
// float down below it.
// (3) Similar a volatile write cannot let unrelated NON-volatile
// memory refs that happen BEFORE the write float down to after the
// write. It's OK for non-volatile memory refs that happen after the
// volatile write to float up before it.
//
// We only put in barriers around volatile refs (they are expensive),
// not _between_ memory refs (that would require us to track the
// flavor of the previous memory refs). Requirements (2) and (3)
// require some barriers before volatile stores and after volatile
// loads. These nearly cover requirement (1) but miss the
// volatile-store-volatile-load case. This final case is placed after
// volatile-stores although it could just as well go before
// volatile-loads.

void TemplateTable::volatile_barrier(Assembler::Membar_mask_bits order_constraint ) {
// Helper function to insert a is-volatile test and memory barrier
__ membar(order_constraint);
}

还有这段:

ConstantPoolCache 看上去是运行时从.class文件读取的内容, 这里就有volatile的标志位,我们看看是在哪里设置这个值ConstantPoolCacheEntry::is_volatile_shift

// The ConstantPoolCache is not a cache! It is the resolution table that the
// interpreter uses to avoid going into the runtime and a way to access resolved
// values.

// A ConstantPoolCacheEntry describes an individual entry of the constant
// pool cache. There's 2 principal kinds of entries: field entries for in-
// stance & static field access, and method entries for invokes. Some of
// the entry layout is shared and looks as follows:
//
// bit number |31 0|
// bit length |-8--|-8--|---16----|
// --------------------------------
// _indices [ b2 | b1 | index ] index = constant_pool_index
// _f1 [ entry specific ] metadata ptr (method or klass)
// _f2 [ entry specific ] vtable or res_ref index, or vfinal method ptr
// _flags [tos|0|F=1|0|0|0|f|v|0 |0000|field_index] (for field entries)
// bit length [ 4 |1| 1 |1|1|1|1|1|1 |1 |-3-|----16-----]
// _flags [tos|0|F=0|S|A|I|f|0|vf|indy_rf|000|00000|psize] (for method entries)
// bit length [ 4 |1| 1 |1|1|1|1|1|1 |-4--|--8--|--8--]

// --------------------------------
//
// with:
// index = original constant pool index
// b1 = bytecode 1
// b2 = bytecode 2
// psize = parameters size (method entries only)
// field_index = index into field information in holder InstanceKlass
// The index max is 0xffff (max number of fields in constant pool)
// and is multiplied by (InstanceKlass::next_offset) when accessing.
// tos = TosState
// F = the entry is for a field (or F=0 for a method)
// A = call site has an appendix argument (loaded from resolved references)
// I = interface call is forced virtual (must use a vtable index or vfinal)
// f = field or method is final
// v = field is volatile
// vf = virtual but final (method entries only: is_vfinal())
// indy_rf = call site specifier method resolution failed
//
// The flags after TosState have the following interpretation:
// bit 27: 0 for fields, 1 for methods
// f flag true if field is marked final
// v flag true if field is volatile (only for fields)
// f2 flag true if f2 contains an oop (e.g., virtual final method)
// fv flag true if invokeinterface used for method in class Object
//
// The flags 31, 30, 29, 28 together build a 4 bit number 0 to 16 with the
// following mapping to the TosState states:
//
// btos: 0
// ztos: 1
// ctos: 2
// stos: 3
// itos: 4
// ltos: 5
// ftos: 6
// dtos: 7
// atos: 8
// vtos: 9
//
// Entry specific: field entries:
// _indices = get (b1 section) and put (b2 section) bytecodes, original constant pool index
// _f1 = field holder (as a java.lang.Class, not a Klass*)
// _f2 = field offset in bytes
// _flags = field type information, original FieldInfo index in field holder
// (field_index section)
//
// Entry specific: method entries:
// _indices = invoke code for f1 (b1 section), invoke code for f2 (b2 section),
// original constant pool index
// _f1 = Method* for non-virtual calls, unused by virtual calls.
// for interface calls, which are essentially virtual but need a klass,
// contains Klass* for the corresponding interface.
// for invokedynamic and invokehandle, f1 contains the adapter method which
// manages the actual call. The appendix is stored in the ConstantPool
// resolved_references array.
// (upcoming metadata changes will move the appendix to a separate array)
// _f2 = vtable/itable index (or final Method*) for virtual calls only,
// unused by non-virtual. The is_vfinal flag indicates this is a
// method pointer for a final method, not an index.
// _flags = has local signature (MHs and indy),
// virtual final bit (vfinal),
// parameter size (psize section)
//
// Note: invokevirtual & invokespecial bytecodes can share the same constant
// pool entry and thus the same constant pool cache entry. All invoke
// bytecodes but invokevirtual use only _f1 and the corresponding b1
// bytecode, while invokevirtual uses only _f2 and the corresponding
// b2 bytecode. The value of _flags is shared for both types of entries.
//
// The fields are volatile so that they are stored in the order written in the
// source code. The _indices field with the bytecode must be written last.

class CallInfo;

class ConstantPoolCacheEntry {

然后我们看看设置值的地方在这里

 //源码地址   src/hotspot/share/oops/cpCache.cpp

// Note that concurrent update of both bytecodes can leave one of them
// reset to zero. This is harmless; the interpreter will simply re-resolve
// the damaged entry. More seriously, the memory synchronization is needed
// to flush other fields (f1, f2) completely to memory before the bytecodes
// are updated, lest other processors see a non-zero bytecode but zero f1/f2.
void ConstantPoolCacheEntry::set_field(Bytecodes::Code get_code,
Bytecodes::Code put_code,
Klass* field_holder,
int field_index,
int field_offset,
TosState field_type,
bool is_final,
bool is_volatile) {
set_f1(field_holder);
set_f2(field_offset);
assert((field_index & field_index_mask) == field_index,
"field index does not fit in low flag bits");
set_field_flags(field_type,
((is_volatile ? 1 : 0) << is_volatile_shift) | <--- 在这里会设置volatile 的值
((is_final ? 1 : 0) << is_final_shift),
field_index);
set_bytecode_1(get_code);
set_bytecode_2(put_code);
NOT_PRODUCT(verify(tty));
}

然后用gdb调试一下:

(gdb) bt
#0 b ::set_field (this=0x7fffb4151b50, get_code=Bytecodes::_nop, put_code=Bytecodes::_nop, field_holder=0x800042fa0, field_index=2, field_offset=120, field_type=atos,
is_final=true, is_volatile=false) at /home/dai/jdk/src/hotspot/share/oops/cpCache.cpp:139
#1 0x00007ffff65d2561 in InterpreterRuntime::resolve_get_put (current=0x7ffff0028f70, bytecode=Bytecodes::_putstatic) at /home/dai/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:708
#2 0x00007ffff65d3e14 in InterpreterRuntime::resolve_from_cache (current=0x7ffff0028f70, bytecode=Bytecodes::_putstatic) at /home/dai/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:959
#3 0x00007fffe10203e3 in ?? ()
#4 0x00007ffff7bcc0a0 in TemplateInterpreter::_active_table () from /home/dai/jdk/build/linux-x86_64-server-slowdebug/jdk/lib/server/libjvm.so
#5 0x00007fffe1020362 in ?? ()
#6 0x0000000000000000 in ?? ()

我们看看ConstantPoolCacheEntry是从哪里取的

// Helper class to access current interpreter state
class LastFrameAccessor : public StackObj {
frame _last_frame;
public:
...
ConstantPoolCacheEntry* cache_entry_at(int i) const
{ return method()->constants()->cache()->entry_at(i); }
ConstantPoolCacheEntry* cache_entry() const { return cache_entry_at(Bytes::get_native_u2(bcp() + 1)); }
}
(gdb) p m->print()
{method}
- this oop: 0x00007fffd14108e8
- method holder: 'java/lang/String'
- constants: 0x00007fffd14013b8 constant pool [1396]/operands[28] {0x00007fffd14013b8} for 'java/lang/String' cache=0x00007fffd1544158
- access: 0x8 static
- name: '<clinit>'
- signature: '()V'
- max stack: 3
- max locals: 0
- size of params: 0
- method size: 13
- vtable index: -2
- i2i entry: 0x00007fffe100dbe0
- adapters: AHE@0x00007ffff009b550: 0x i2c: 0x00007fffe1115060 c2i: 0x00007fffe111510d c2iUV: 0x00007fffe11150e0 c2iNCI: 0x00007fffe111514a
- compiled entry 0x00007fffe111510d
- code size: 22
- code start: 0x00007fffd14108c0
- code end (excl): 0x00007fffd14108d6
- checked ex length: 0
- linenumber start: 0x00007fffd14108d6
- localvar length: 0
$7 = void
(gdb) bt
#0 frame::interpreter_frame_method (this=0x7ffff5aa43f8) at /home/ubuntu/daixiao/jdk/src/hotspot/share/runtime/frame.cpp:332
#1 0x00007ffff672253c in LastFrameAccessor::method (this=0x7ffff5aa43f0) at /home/ubuntu/daixiao/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:90
#2 0x00007ffff671d2fb in InterpreterRuntime::resolve_get_put (current=0x7ffff0028940, bytecode=Bytecodes::_putstatic) at /home/ubuntu/daixiao/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:650
#3 0x00007ffff671ec81 in InterpreterRuntime::resolve_from_cache (current=0x7ffff0028940, bytecode=Bytecodes::_putstatic) at /home/ubuntu/daixiao/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:948
#4 0x00007fffe10203a3 in ?? ()
#5 0x00007ffff7d4b280 in TemplateInterpreter::_active_table () from /home/ubuntu/daixiao/jdk/build/linux-x86_64-server-slowdebug/jdk/lib/server/libjvm.so
#6 0x00007fffe1020322 in ?? ()
#7 0x0000000000000001 in ?? ()
#8 0x00007ffff5aa44d8 in ?? ()
#9 0x00007fffd14108c1 in ?? ()
#10 0x00007ffff5aa4528 in ?? ()
#11 0x00007fffd1544158 in ?? ()
#12 0x0000000000000000 in ?? ()
(gdb)

解析cache

InterpreterRuntime::resolve_from_cache

LinkResolver::resolve_field_access

相关类在

//   src/hotspot/share/oops/cpCache.cpp
// 头文件 在 src/hotspot/share/oops/cpCache.hpp
ConstantPoolCacheEntry

问了一下chatgpt

在HotSpot JVM中,ConstantPoolCacheEntry对象是在解析类文件时动态创建的。具体来说,在解析类文件时,JVM会为类文件中的每个常量创建一个对应的ConstantPoolCacheEntry对象,并将其添加到类的常量池缓存中。

ConstantPoolCacheEntry对象的实例化主要是在ClassFileParser类的parse_constant_pool_entry()函数中完成的。在解析常量池时,parse_constant_pool_entry()函数会根据常量的类型和值动态创建一个对应的ConstantPoolCacheEntry对象,并将其添加到类的常量池缓存中。

需要注意的是,在解析过程中,JVM可能会使用占位符对象来表示无效的或未知的常量,而不是创建ConstantPoolCacheEntry对象。在这种情况下,JVM会将占位符对象添加到常量池缓存中,以便在解析和执行时可以快速跳过无效的或未知的常量。

总之,在HotSpot JVM中,ConstantPoolCacheEntry对象的实例化是在解析类文件时完成的,而具体实现是在ClassFileParser类的parse_constant_pool_entry()函数中完成的。

查看堆栈

(gdb) p stream->_source
$4 = 0x7ffff00bdd40 "/home/ubuntu/daixiao/jdk/build/linux-x86_64-server-slowdebug/jdk/modules/java.base"
(gdb) bt
#0 ClassFileParser::parse_constant_pool_entries (this=0x7ffff0028940, stream=0x0, cp=0x7ffff5fadff1 <Thread::as_Java_thread()+39>, length=32767, __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/classFileParser.cpp:150
#1 0x00007ffff6378b5e in ClassFileParser::parse_constant_pool (this=0x7ffff5aa27e0, stream=0x7ffff00298e0, cp=0x7fffd169b1c8, length=31, __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/classFileParser.cpp:424
#2 0x00007ffff638aacc in ClassFileParser::parse_stream (this=0x7ffff5aa27e0, stream=0x7ffff00298e0, __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/classFileParser.cpp:5720
#3 0x00007ffff638a2b1 in ClassFileParser::ClassFileParser (this=0x7ffff5aa27e0, stream=0x7ffff00298e0, name=0x7fffb005b0a0, loader_data=0x7ffff0091890, cl_info=0x7ffff5aa2a10, pub_level=ClassFileParser::BROADCAST, __the_thread__=0x7ffff0028940)
at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/classFileParser.cpp:5590
#4 0x00007ffff69d5f1f in KlassFactory::create_from_stream (stream=0x7ffff00298e0, name=0x7fffb005b0a0, loader_data=0x7ffff0091890, cl_info=..., __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/klassFactory.cpp:199
#5 0x00007ffff639a9e5 in ClassLoader::load_class (name=0x7fffb005b0a0, search_append_only=false, __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/classLoader.cpp:1222
#6 0x00007ffff6e97300 in SystemDictionary::load_instance_class_impl (class_name=0x7fffb005b0a0, class_loader=..., __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/systemDictionary.cpp:1290
#7 0x00007ffff6e976d1 in SystemDictionary::load_instance_class (name_hash=1923324215, name=0x7fffb005b0a0, class_loader=..., __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/systemDictionary.cpp:1356
#8 0x00007ffff6e95874 in SystemDictionary::resolve_instance_class_or_null (name=0x7fffb005b0a0, class_loader=..., protection_domain=..., __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/systemDictionary.cpp:724
#9 0x00007ffff6e94481 in SystemDictionary::resolve_instance_class_or_null_helper (class_name=0x7fffb005b0a0, class_loader=..., protection_domain=..., __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/systemDictionary.cpp:295
#10 0x00007ffff6e94330 in SystemDictionary::resolve_or_null (class_name=0x7fffb005b0a0, class_loader=..., protection_domain=..., __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/systemDictionary.cpp:278
#11 0x00007ffff6e94273 in SystemDictionary::resolve_or_fail (class_name=0x7fffb005b0a0, class_loader=..., protection_domain=..., throw_error=true, __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/systemDictionary.cpp:264
#12 0x00007ffff64314d1 in ConstantPool::klass_at_impl (this_cp=..., which=506, __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/oops/constantPool.cpp:512
#13 0x00007ffff62aca88 in ConstantPool::klass_at (this=0x7fffd1692c38, which=506, __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/oops/constantPool.hpp:420
#14 0x00007ffff671af3a in InterpreterRuntime::_new (current=0x7ffff0028940, pool=0x7fffd1692c38, index=506) at /home/ubuntu/daixiao/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:219
#15 0x00007fffe1023b92 in ?? ()
#16 0x00007fffe1023b06 in ?? ()
#17 0x00007ffff5aa3368 in ?? ()
#18 0x00007fffd1699fe1 in ?? ()
#19 0x00007ffff5aa33b8 in ?? ()
#20 0x00007fffd169a0a0 in ?? ()
#21 0x0000000000000000 in ?? ()

设置断点

(gdb) commands
Type commands for breakpoint(s) 5, one per line.
End with a line saying just "end".
>p name->print()
>c
>end

打印

Thread 2 "java" hit Breakpoint 5, KlassFactory::create_from_stream (stream=0x7ffff5aa2f20, name=0x7ffff044c4a0, loader_data=0x7ffff03ddf90, cl_info=..., __the_thread__=0x7ffff0028940) at /home/ubuntu/daixiao/jdk/src/hotspot/share/classfile/klassFactory.cpp:172
172 assert(loader_data != NULL, "invariant");
Symbol: 'com/HelloWorld' count 2$1035 = void

类加载

$801 = 0x7ffff59fd0b0 "file:/home/dai/jdk/build/linux-x86_64-server-slowdebug/jdk/bin/"
(gdb) bt
#0 KlassFactory::create_from_stream (stream=0x7ffff59fce00, name=0x7ffff057a9d0, loader_data=0x7ffff05185c0, cl_info=..., __the_thread__=0x7ffff0028f50)
at /home/dai/jdk/src/hotspot/share/classfile/klassFactory.cpp:179
#1 0x00007ffff6d4248e in SystemDictionary::resolve_class_from_stream (st=0x7ffff59fce00, class_name=0x7ffff057a9d0, class_loader=..., cl_info=..., __the_thread__=0x7ffff0028f50)
at /home/dai/jdk/src/hotspot/share/classfile/systemDictionary.cpp:914
#2 0x00007ffff6d42708 in SystemDictionary::resolve_from_stream (st=0x7ffff59fce00, class_name=0x7ffff057a9d0, class_loader=..., cl_info=..., __the_thread__=0x7ffff0028f50)
at /home/dai/jdk/src/hotspot/share/classfile/systemDictionary.cpp:952
#3 0x00007ffff66e1b51 in jvm_define_class_common (name=0x7ffff59fd030 "Hello", loader=0x7ffff59fd5a0, buf=0x7ffff04a4b90 "\312\376\272\276", len=409, pd=0x7ffff59fd578,
source=0x7ffff59fd0b0 "file:/home/dai/jdk/build/linux-x86_64-server-slowdebug/jdk/bin/", __the_thread__=0x7ffff0028f50) at /home/dai/jdk/src/hotspot/share/prims/jvm.cpp:883
#4 0x00007ffff66e2832 in JVM_DefineClassWithSource (env=0x7ffff0029230, name=0x7ffff59fd030 "Hello", loader=0x7ffff59fd5a0, buf=0x7ffff04a4b90 "\312\376\272\276", len=409, pd=0x7ffff59fd578,
source=0x7ffff59fd0b0 "file:/home/dai/jdk/build/linux-x86_64-server-slowdebug/jdk/bin/") at /home/dai/jdk/src/hotspot/share/prims/jvm.cpp:1047
#5 0x00007ffff58db1f5 in Java_java_lang_ClassLoader_defineClass1 (env=0x7ffff0029230, cls=0x7ffff59fd560, loader=0x7ffff59fd5a0, name=0x7ffff59fd598, data=0x7ffff59fd590, offset=0, length=409,
pd=0x7ffff59fd578, source=0x7ffff59fd570) at /home/dai/jdk/src/java.base/share/native/libjava/ClassLoader.c:132
#6 0x00007fffe100f6cb in ?? ()
#7 0x0000000000000199 in ?? ()
#8 0x00007ffff59fd578 in ?? ()
#9 0x00007ffff59fd570 in ?? ()
#10 0x0000555555581230 in ?? ()
#11 0x00007ffff0028f50 in ?? ()
#12 0x00007fffb445ba08 in ?? ()
#13 0x00007fffe100f199 in ?? ()
#14 0x00007ffff59fd508 in ?? ()
#15 0x00007fffb4025170 in ?? ()
#16 0x00007ffff59fd5a0 in ?? ()
#17 0x00007fffb4147588 in ?? ()
#18 0x0000000000000000 in ?? ()

fileinfo 如何初始化

ConstantPoolCacheEntry 是由fieldDescriptor 的字段传进去的 , 那么我们看看fieldDescriptor是怎么初始化的

  fieldDescriptor info;
...
void InterpreterRuntime::resolve_get_put(JavaThread* current, Bytecodes::Code bytecode) {
...

LinkResolver::resolve_field_access(info, pool, last_frame.get_index_u2_cpcache(bytecode),
m, bytecode, CHECK);
...


}

我们最后找到初始化的地方

bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
Symbol* f_name = fs.name();
Symbol* f_sig = fs.signature();
if (f_name == name && f_sig == sig) {
fd->reinitialize(const_cast<InstanceKlass*>(this), fs.index()); // 初始化的地方
return true;
}
}
return false;
}

初始化就在这里: fieldDescriptor::reinitialize

void fieldDescriptor::reinitialize(InstanceKlass* ik, int index) {
...
FieldInfo* f = ik->field(index);
_access_flags = accessFlags_from(f->access_flags());
guarantee(f->name_index() != 0 && f->signature_index() != 0, "bad constant pool index for fieldDescriptor");
_index = index;
...
}

jvm 堆栈结构

inline frame ContinuationEntry::to_frame() const {
static CodeBlob* cb = CodeCache::find_blob_fast(entry_pc());
assert(cb != nullptr, "");
assert(cb->as_compiled_method()->method()->is_continuation_enter_intrinsic(), "");
return frame(entry_sp(), entry_sp(), entry_fp(), entry_pc(), cb);
}
(gdb) bt
#0 frame::frame (this=0x7ffff59fe348) at /home/dai/jdk/src/hotspot/cpu/x86/frame_x86.inline.hpp:37
#1 0x00007ffff65d76f1 in LastFrameAccessor::LastFrameAccessor (this=0x7ffff59fe340, current=0x7ffff0028f70)
at /home/dai/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:84
#2 0x00007ffff65d212e in InterpreterRuntime::resolve_get_put (current=0x7ffff0028f70,
bytecode=Bytecodes::_putstatic) at /home/dai/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:652
#3 0x00007ffff65d3e14 in InterpreterRuntime::resolve_from_cache (current=0x7ffff0028f70,
bytecode=Bytecodes::_putstatic) at /home/dai/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:959
#4 0x00007fffe10203e3 in ?? ()
#5 0x00007ffff7bca0a0 in TemplateInterpreter::_active_table ()
from /home/dai/jdk/build/linux-x86_64-server-slowdebug/jdk/lib/server/libjvm.so
#6 0x00007fffe1020362 in ?? ()
#7 0x0000000000000001 in ?? ()
#8 0x00007ffff59fe438 in ?? ()
#9 0x00007fffb4010821 in ?? ()
#10 0x00007ffff59fe488 in ?? ()
#11 0x00007fffb4149b38 in ?? ()
#12 0x0000000000000000 in ?? ()

后面我们能看到初始化是在这里:

frame JavaThread::pd_last_frame() {
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
}

frame 的初始化

(gdb) bt
#0 JavaThread::pd_last_frame (this=0x7ffff0028f70) at /home/dai/jdk/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp:30
#1 0x00007ffff612888b in JavaThread::last_frame (this=0x7ffff0028f70) at /home/dai/jdk/src/hotspot/share/runtime/thread.hpp:1407
#2 0x00007ffff65d7757 in LastFrameAccessor::LastFrameAccessor (this=0x7ffff59fe340, current=0x7ffff0028f70) at /home/dai/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:86
#3 0x00007ffff65d212e in InterpreterRuntime::resolve_get_put (current=0x7ffff0028f70, bytecode=Bytecodes::_putstatic) at /home/dai/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:652
#4 0x00007ffff65d3e14 in InterpreterRuntime::resolve_from_cache (current=0x7ffff0028f70, bytecode=Bytecodes::_putstatic) at /home/dai/jdk/src/hotspot/share/interpreter/interpreterRuntime.cpp:959
#5 0x00007fffe10203e3 in ?? ()
#6 0x00007ffff7bca0a0 in TemplateInterpreter::_active_table () from /home/dai/jdk/build/linux-x86_64-server-slowdebug/jdk/lib/server/libjvm.so
#7 0x00007fffe1020362 in ?? ()
#8 0x0000000000000001 in ?? ()
#9 0x00007ffff59fe438 in ?? ()
#10 0x00007fffb4010821 in ?? ()
#11 0x00007ffff59fe488 in ?? ()
#12 0x00007fffb4149b38 in ?? ()
#13 0x0000000000000000 in ?? ()
(gdb) list
35 // For Forte Analyzer AsyncGetCallTrace profiling support - thread is
36 // currently interrupted by SIGPROF
37 bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
38 void* ucontext, bool isInJava) {
39
40 assert(Thread::current() == this, "caller must be current thread");
41 return pd_get_top_frame(fr_addr, ucontext, isInJava);
42 }
43
44 bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
(gdb) info registers
rax 0x7ffff59fe220 140737314284064
rbx 0x7ffff59fe340 140737314284352
rcx 0x7ffff00153f0 140737220006896
rdx 0x7ffff0028f70 140737220087664
rsi 0x7ffff0028f70 140737220087664
rdi 0x7ffff59fe220 140737314284064
rbp 0x7ffff59fe1f0 0x7ffff59fe1f0
rsp 0x7ffff59fe1d0 0x7ffff59fe1d0
r8 0x8 8
r9 0x0 0
r10 0x7ffff7bca0a0 140737349722272
r11 0x7ffff0000090 140737219920016
r12 0x0 0
r13 0x7fffb4010821 140736213354529
r14 0x7ffff59fe488 140737314284680
r15 0x7ffff0028f70 140737220087664
rip 0x7ffff6da2ea3 0x7ffff6da2ea3 <JavaThread::pd_last_frame()+23>
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0

然后我们看到在

  JavaFrameAnchor _anchor;    

class JavaFrameAnchor {
...

private:
...
intptr_t* volatile _last_Java_sp; //stack_pointer
...
}

JavaFrameAnchor 初始化

JavaFrameAnchor::clear (this=0x7ffff0029230) at /home/dai/jdk/src/hotspot/cpu/x86/javaFrameAnchor_x86.hpp:44
44 _last_Java_fp = NULL;
(gdb) bt
#0 JavaFrameAnchor::clear (this=0x7ffff0029230) at /home/dai/jdk/src/hotspot/cpu/x86/javaFrameAnchor_x86.hpp:44
#1 0x00007ffff65df910 in JavaFrameAnchor::JavaFrameAnchor (this=0x7ffff0029230) at /home/dai/jdk/src/hotspot/share/runtime/javaFrameAnchor.hpp:88
#2 0x00007ffff6d8730c in JavaThread::JavaThread (this=0x7ffff0028f70) at /home/dai/jdk/src/hotspot/share/runtime/thread.cpp:1076
#3 0x00007ffff6d8d0ee in Threads::create_vm (args=0x7ffff59fed50, canTryAgain=0x7ffff59fec5b) at /home/dai/jdk/src/hotspot/share/runtime/thread.cpp:2817
#4 0x00007ffff66b243b in JNI_CreateJavaVM_inner (vm=0x7ffff59feda8, penv=0x7ffff59fedb0, args=0x7ffff59fed50) at /home/dai/jdk/src/hotspot/share/prims/jni.cpp:3613
#5 0x00007ffff66b2787 in JNI_CreateJavaVM (vm=0x7ffff59feda8, penv=0x7ffff59fedb0, args=0x7ffff59fed50) at /home/dai/jdk/src/hotspot/share/prims/jni.cpp:3701
#6 0x00007ffff7faca6a in InitializeJVM (pvm=0x7ffff59feda8, penv=0x7ffff59fedb0, ifn=0x7ffff59fee00) at /home/dai/jdk/src/java.base/share/native/libjli/java.c:1459
#7 0x00007ffff7fa95ec in JavaMain (_args=0x7fffffffa9a0) at /home/dai/jdk/src/java.base/share/native/libjli/java.c:411
#8 0x00007ffff7fb05ec in ThreadJavaMain (args=0x7fffffffa9a0) at /home/dai/jdk/src/java.base/unix/native/libjli/java_md.c:651
#9 0x00007ffff7c94b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#10 0x00007ffff7d26a00 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

在这里会设置last_java_sp

void MacroAssembler::call_VM_base(Register oop_result,
Register java_thread,
Register last_java_sp,
address entry_point,
int number_of_arguments,
bool check_exceptions) {
// determine java_thread register
if (!java_thread->is_valid()) {
#ifdef _LP64
java_thread = r15_thread;
#else
java_thread = rdi;
get_thread(java_thread);
#endif // LP64
}
// determine last_java_sp register
if (!last_java_sp->is_valid()) {
last_java_sp = rsp;
}
// debugging support
assert(number_of_arguments >= 0 , "cannot have negative number of arguments");
LP64_ONLY(assert(java_thread == r15_thread, "unexpected register"));
#ifdef ASSERT
// TraceBytecodes does not use r12 but saves it over the call, so don't verify
// r12 is the heapbase.
LP64_ONLY(if (UseCompressedOops && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");)
#endif // ASSERT

assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result");
assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp");

// push java thread (becomes first argument of C function)

NOT_LP64(push(java_thread); number_of_arguments++);
LP64_ONLY(mov(c_rarg0, r15_thread));

// set last Java frame before call
assert(last_java_sp != rbp, "can't use ebp/rbp");

// Only interpreter should have to set fp
set_last_Java_frame(java_thread, last_java_sp, rbp, NULL);

// do the call, remove parameters
MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments);

// restore the thread (cannot use the pushed argument since arguments
// may be overwritten by C code generated by an optimizing compiler);
// however can use the register value directly if it is callee saved.
if (LP64_ONLY(true ||) java_thread == rdi || java_thread == rsi) {
// rdi & rsi (also r15) are callee saved -> nothing to do
#ifdef ASSERT
guarantee(java_thread != rax, "change this code");
push(rax);
{ Label L;
get_thread(rax);
cmpptr(java_thread, rax);
jcc(Assembler::equal, L);
STOP("MacroAssembler::call_VM_base: rdi not callee saved?");
bind(L);
}
pop(rax);
#endif
} else {
get_thread(java_thread);
}
// reset last Java frame
// Only interpreter should have to clear fp
reset_last_Java_frame(java_thread, true);

// C++ interp handles this in the interpreter
check_and_handle_popframe(java_thread);
check_and_handle_earlyret(java_thread);

if (check_exceptions) {
// check for pending exceptions (java_thread is set upon return)
cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD);
#ifndef _LP64
jump_cc(Assembler::notEqual,
RuntimeAddress(StubRoutines::forward_exception_entry()));
#else
// This used to conditionally jump to forward_exception however it is
// possible if we relocate that the branch will not reach. So we must jump
// around so we can always reach

Label ok;
jcc(Assembler::equal, ok);
jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
bind(ok);
#endif // LP64
}

// get oop result if there is one and reset the value in the thread
if (oop_result->is_valid()) {
get_vm_result(oop_result, java_thread);
}
}

volatile 标志位

///home/dai/jdk/src/hotspot/share/utilities/accessFlags.hpp
bool is_volatile () const { return (_flags & JVM_ACC_VOLATILE ) != 0; }

相关阅读

java integer divison

· 4 min read

背景

了解java整除除法的规则

jls 描述

Integer division rounds toward 0. That is, the quotient produced for operands n
and d that are integers after binary numeric promotion (§5.6) is an integer value q
whose magnitude is as large as possible while satisfying |d ⋅ q| ≤ |n|. Moreover, q
is positive when |n| ≥ |d| and n and d have the same sign, but q is negative when
|n| ≥ |d| and n and d have opposite signs.

也就是

int res = 3 / 5 = 0 ;

最后使用的bytecode 是idiv

我们看看idiv 这个bytecode 是怎么实现的吧:

jvm 实现

void Assembler::idivl(Register src) {
int encode = prefix_and_encode(src->encoding());
emit_int16((unsigned char)0xF7, (0xF8 | encode));
}

void Assembler::divl(Register src) { // Unsigned
int encode = prefix_and_encode(src->encoding());
emit_int16((unsigned char)0xF7, (0xF0 | encode));
}

查看intel的文档: intel

2.1.5 Addressing-Mode Encoding of ModR/M and SIB Bytes
The values and corresponding addressing forms of the ModR/M and SIB bytes are shown in Table 2-1 through Table
2-3: 16-bit addressing forms specified by the ModR/M byte are in Table 2-1 and 32-bit addressing forms are in
Table 2-2. Table 2-3 shows 32-bit addressing forms specified by the SIB byte. In cases where the reg/opcode field
in the ModR/M byte represents an extended opcode, valid encodings are shown in Appendix B.
In Table 2-1 and Table 2-2, the Effective Address column lists 32 effective addresses that can be assigned to the
first operand of an instruction by using the Mod and R/M fields of the ModR/M byte. The first 24 options provide
ways of specifying a memory location; the last eight (Mod = 11B) provide ways of specifying general-purpose, MMX
technology and XMM registers.
The Mod and R/M columns in Table 2-1 and Table 2-2 give the binary encodings of the Mod and R/M fields required
to obtain the effective address listed in the first column. For example: see the row indicated by Mod = 11B, R/M =
000B. The row identifies the general-purpose registers EAX, AX or AL; MMX technology register MM0; or XMM
register XMM0. The register used is determined by the opcode byte and the operand-size attribute.
Now look at the seventh row in either table (labeled “REG =”). This row specifies the use of the 3-bit Reg/Opcode
field when the field is used to give the location of a second operand. The second operand must be a generalpurpose, MMX technology, or XMM register. Rows one through five list the registers that may correspond to the
value in the table. Again, the register used is determined by the opcode byte along with the operand-size attribute.
If the instruction does not require a second operand, then the Reg/Opcode field may be used as an opcode extension. This use is represented by the sixth row in the tables (labeled “/digit (Opcode)”). Note that values in row six
are represented in decimal form.
The body of Table 2-1 and Table 2-2 (under the label “Value of ModR/M Byte (in Hexadecimal)”) contains a 32 by
8 array that presents all of 256 values of the ModR/M byte (in hexadecimal). Bits 3, 4 and 5 are specified by the
column of the table in which a byte resides. The row specifies bits 0, 1 and 2; and bits 6 and 7. The figure below
demonstrates interpretation of one table value.

register 寄存器会从0编码到16,编码顺序如上述所示

例子

int main(void){                        
int num0 = 5;
int num1 = 2;
int num = num0 / num1 ;
return num;
}
## 编译
gcc -O0 test.c -o test

## 用objdump 列出汇编内容
objdump -d test | grep -A20 '<main>:'

结果为

0000000000001129 <main>:
1129: f3 0f 1e fa endbr64
112d: 55 push %rbp
112e: 48 89 e5 mov %rsp,%rbp
1131: c7 45 f4 05 00 00 00 movl $0x5,-0xc(%rbp)
1138: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp)
113f: 8b 45 f4 mov -0xc(%rbp),%eax
1142: 99 cltd
1143: f7 7d f8 idivl -0x8(%rbp)
1146: 89 45 fc mov %eax,-0x4(%rbp)
1149: 8b 45 fc mov -0x4(%rbp),%eax
114c: 5d pop %rbp
114d: c3 retq
114e: 66 90 xchg %ax,%ax

相关阅读

java rabbitmq 初始化

· 2 min read

背景

了解java的spring boot 的rabbitmq的启动流程

堆栈

declareQueues:700, RabbitAdmin (org.springframework.amqp.rabbit.core)
lambda$initialize$12:606, RabbitAdmin (org.springframework.amqp.rabbit.core)
doInRabbit:-1, 1826902085 (org.springframework.amqp.rabbit.core.RabbitAdmin$$Lambda$965)
invokeAction:2151, RabbitTemplate (org.springframework.amqp.rabbit.core)
doExecute:2110, RabbitTemplate (org.springframework.amqp.rabbit.core)
execute:2062, RabbitTemplate (org.springframework.amqp.rabbit.core)
execute:2042, RabbitTemplate (org.springframework.amqp.rabbit.core)
initialize:604, RabbitAdmin (org.springframework.amqp.rabbit.core)
lambda$null$10:532, RabbitAdmin (org.springframework.amqp.rabbit.core)
doWithRetry:-1, 999782961 (org.springframework.amqp.rabbit.core.RabbitAdmin$$Lambda$957)
doExecute:287, RetryTemplate (org.springframework.retry.support)
execute:164, RetryTemplate (org.springframework.retry.support)
lambda$afterPropertiesSet$11:531, RabbitAdmin (org.springframework.amqp.rabbit.core)
onCreate:-1, 1185831500 (org.springframework.amqp.rabbit.core.RabbitAdmin$$Lambda$950)
lambda$onCreate$0:38, CompositeConnectionListener (org.springframework.amqp.rabbit.connection)
accept:-1, 1588281004 (org.springframework.amqp.rabbit.connection.CompositeConnectionListener$$Lambda$956)
forEach:803, CopyOnWriteArrayList (java.util.concurrent)
onCreate:38, CompositeConnectionListener (org.springframework.amqp.rabbit.connection)
createConnection:757, CachingConnectionFactory (org.springframework.amqp.rabbit.connection)
createConnection:216, ConnectionFactoryUtils (org.springframework.amqp.rabbit.connection)
doExecute:2089, RabbitTemplate (org.springframework.amqp.rabbit.core)
execute:2062, RabbitTemplate (org.springframework.amqp.rabbit.core)
execute:2042, RabbitTemplate (org.springframework.amqp.rabbit.core)
declareExchange:221, RabbitAdmin (org.springframework.amqp.rabbit.core)
cdpOrderTopicExchange:27, RabbitConfig (com.patpat.mms.mdp.base.core.rest.config)
CGLIB$cdpOrderTopicExchange$7:-1, RabbitConfig$$EnhancerBySpringCGLIB$$65dbc353 (com.patpat.mms.mdp.base.core.rest.config)
invoke:-1, RabbitConfig$$EnhancerBySpringCGLIB$$65dbc353$$FastClassBySpringCGLIB$$bdc910b3 (com.patpat.mms.mdp.base.core.rest.config)
invokeSuper:244, MethodProxy (org.springframework.cglib.proxy)
intercept:331, ConfigurationClassEnhancer$BeanMethodInterceptor (org.springframework.context.annotation)
cdpOrderTopicExchange:-1, RabbitConfig$$EnhancerBySpringCGLIB$$65dbc353 (com.patpat.mms.mdp.base.core.rest.config)
invoke0:-1, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:62, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:43, DelegatingMethodAccessorImpl (jdk.internal.reflect)
invoke:566, Method (java.lang.reflect)
instantiate:154, SimpleInstantiationStrategy (org.springframework.beans.factory.support)
instantiate:652, ConstructorResolver (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:637, ConstructorResolver (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:1341, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBeanInstance:1181, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:556, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:516, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 1735872041 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$295)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:322, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:897, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:879, AbstractApplicationContext (org.springframework.context.support)
refresh:551, AbstractApplicationContext (org.springframework.context.support)
refresh:755, SpringApplication (org.springframework.boot)
refresh:747, SpringApplication (org.springframework.boot)
refreshContext:402, SpringApplication (org.springframework.boot)
run:312, SpringApplication (org.springframework.boot)
loadContext:120, SpringBootContextLoader (org.springframework.boot.test.context)
loadContextInternal:99, DefaultCacheAwareContextLoaderDelegate (org.springframework.test.context.cache)
loadContext:124, DefaultCacheAwareContextLoaderDelegate (org.springframework.test.context.cache)
getApplicationContext:123, DefaultTestContext (org.springframework.test.context.support)
setUpRequestContextIfNecessary:190, ServletTestExecutionListener (org.springframework.test.context.web)
prepareTestInstance:132, ServletTestExecutionListener (org.springframework.test.context.web)
prepareTestInstance:244, TestContextManager (org.springframework.test.context)
createTest:227, SpringJUnit4ClassRunner (org.springframework.test.context.junit4)
runReflectiveCall:289, SpringJUnit4ClassRunner$1 (org.springframework.test.context.junit4)
run:12, ReflectiveCallable (org.junit.internal.runners.model)
methodBlock:291, SpringJUnit4ClassRunner (org.springframework.test.context.junit4)
runChild:246, SpringJUnit4ClassRunner (org.springframework.test.context.junit4)
runChild:97, SpringJUnit4ClassRunner (org.springframework.test.context.junit4)
run:331, ParentRunner$4 (org.junit.runners)
schedule:79, ParentRunner$1 (org.junit.runners)
runChildren:329, ParentRunner (org.junit.runners)
access$100:66, ParentRunner (org.junit.runners)
evaluate:293, ParentRunner$2 (org.junit.runners)
evaluate:61, RunBeforeTestClassCallbacks (org.springframework.test.context.junit4.statements)
evaluate:70, RunAfterTestClassCallbacks (org.springframework.test.context.junit4.statements)
evaluate:306, ParentRunner$3 (org.junit.runners)
run:413, ParentRunner (org.junit.runners)
run:190, SpringJUnit4ClassRunner (org.springframework.test.context.junit4)
run:137, JUnitCore (org.junit.runner)
startRunnerWithArgs:69, JUnit4IdeaTestRunner (com.intellij.junit4)
execute:38, IdeaTestRunner$Repeater$1 (com.intellij.rt.junit)
repeat:11, TestsRepeater (com.intellij.rt.execution.junit)
startRunnerWithArgs:35, IdeaTestRunner$Repeater (com.intellij.rt.junit)
prepareStreamsAndStart:235, JUnitStarter (com.intellij.rt.junit)
main:54, JUnitStarter (com.intellij.rt.junit)

rabbit mq 多个admin

direct memory in java

· 28 min read

背景

lucene 使用了direct memory,这类内存是非jvm直接管理的内存

DirectByteBufferR 是read only 版本的DirectByteBuffer,所以DirectByteBufferDirectByteBufferR是差不多的类

lucene的mmap

lucene 会使用DirectByteBufferR,这里申请的内存地址是140063879776283

main[1] dump receiver
receiver = {
$assertionsDisabled: true
java.nio.DirectByteBuffer.ARRAY_BASE_OFFSET: 16
java.nio.DirectByteBuffer.UNALIGNED: true
java.nio.DirectByteBuffer.att: instance of java.nio.DirectByteBufferR(id=1500)
java.nio.DirectByteBuffer.cleaner: null
java.nio.DirectByteBuffer.$assertionsDisabled: true
java.nio.MappedByteBuffer.fd: instance of java.io.FileDescriptor(id=1501)
java.nio.MappedByteBuffer.isSync: false
java.nio.MappedByteBuffer.SCOPED_MEMORY_ACCESS: instance of jdk.internal.misc.ScopedMemoryAccess(id=1502)
java.nio.ByteBuffer.ARRAY_BASE_OFFSET: 16
java.nio.ByteBuffer.hb: null
java.nio.ByteBuffer.offset: 0
java.nio.ByteBuffer.isReadOnly: true
java.nio.ByteBuffer.bigEndian: false
java.nio.ByteBuffer.nativeByteOrder: true
java.nio.ByteBuffer.$assertionsDisabled: true
java.nio.Buffer.UNSAFE: instance of jdk.internal.misc.Unsafe(id=1503)
java.nio.Buffer.SCOPED_MEMORY_ACCESS: instance of jdk.internal.misc.ScopedMemoryAccess(id=1502)
java.nio.Buffer.SPLITERATOR_CHARACTERISTICS: 16464
java.nio.Buffer.mark: -1
java.nio.Buffer.position: 0
java.nio.Buffer.limit: 7
java.nio.Buffer.capacity: 7
java.nio.Buffer.address: 140063879776283
java.nio.Buffer.segment: null
java.nio.Buffer.$assertionsDisabled: true
}
main[1] where
[1] org.apache.lucene.store.ByteBufferGuard.getByte (ByteBufferGuard.java:118)
[2] org.apache.lucene.store.ByteBufferIndexInput$SingleBufferImpl.readByte (ByteBufferIndexInput.java:593)
[3] org.apache.lucene.codecs.lucene90.Lucene90NormsProducer$3.longValue (Lucene90NormsProducer.java:388)
[4] org.apache.lucene.search.LeafSimScorer.getNormValue (LeafSimScorer.java:47)
[5] org.apache.lucene.search.LeafSimScorer.score (LeafSimScorer.java:60)
[6] org.apache.lucene.search.TermScorer.score (TermScorer.java:75)
[7] org.apache.lucene.search.TopScoreDocCollector$SimpleTopScoreDocCollector$1.collect (TopScoreDocCollector.java:73)
[8] org.apache.lucene.search.Weight$DefaultBulkScorer.scoreAll (Weight.java:305)
[9] org.apache.lucene.search.Weight$DefaultBulkScorer.score (Weight.java:247)
[10] org.apache.lucene.search.BulkScorer.score (BulkScorer.java:38)
[11] org.apache.lucene.search.IndexSearcher.search (IndexSearcher.java:770)
[12] org.apache.lucene.search.IndexSearcher.search (IndexSearcher.java:693)
[13] org.apache.lucene.search.IndexSearcher.search (IndexSearcher.java:687)
[14] org.apache.lucene.search.IndexSearcher.searchAfter (IndexSearcher.java:532)
[15] org.apache.lucene.search.IndexSearcher.search (IndexSearcher.java:542)
[16] org.apache.lucene.demo.SearchFiles.doPagingSearch (SearchFiles.java:180)
[17] org.apache.lucene.demo.SearchFiles.main (SearchFiles.java:150)

查看_7.cfs 文件:

hexdump -C /home/dai/index/_7.cfs
00000000 3f d7 6c 17 14 4c 75 63 65 6e 65 39 30 43 6f 6d |?.l..Lucene90Com|
00000010 70 6f 75 6e 64 44 61 74 61 00 00 00 00 6b f0 66 |poundData....k.f|
00000020 56 c3 12 5b 07 08 12 3a 32 4d 4b 92 f8 00 00 00 |V..[...:2MK.....|
00000030 3f d7 6c 17 17 4c 75 63 65 6e 65 39 30 46 69 65 |?.l..Lucene90Fie|
00000040 6c 64 73 49 6e 64 65 78 4d 65 74 61 00 00 00 01 |ldsIndexMeta....|
00000050 6b f0 66 56 c3 12 5b 07 08 12 3a 32 4d 4b 92 f8 |k.fV..[...:2MK..|
00000060 00 80 80 05 07 00 00 00 0a 00 00 00 02 00 00 00 |................|
00000070 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |0...............|
00000080 00 00 e0 40 00 00 00 00 00 00 00 00 00 30 00 00 |[email protected]..|
00000090 00 00 00 00 00 36 00 00 00 00 00 00 00 00 00 5d |.....6.........]|
000000a0 43 00 00 00 00 00 00 00 00 00 30 00 00 00 00 00 |C.........0.....|
000000b0 00 00 13 01 00 00 00 00 00 00 01 01 07 c0 28 93 |..............(.|
000000c0 e8 00 00 00 00 00 00 00 00 46 80 fe 32 00 00 00 |.........F..2...|
000000d0 3f d7 6c 17 19 4c 75 63 65 6e 65 39 30 50 6f 69 |?.l..Lucene90Poi|
000000e0 6e 74 73 46 6f 72 6d 61 74 49 6e 64 65 78 00 00 |ntsFormatIndex..|
000000f0 00 00 6b f0 66 56 c3 12 5b 07 08 12 3a 32 4d 4b |..k.fV..[...:2MK|
00000100 92 f8 00 32 c0 28 93 e8 00 00 00 00 00 00 00 00 |...2.(..........|
00000110 0a 2f 94 55 00 00 00 00 3f d7 6c 17 18 4c 75 63 |./.U....?.l..Luc|
00000120 65 6e 65 39 30 50 6f 69 6e 74 73 46 6f 72 6d 61 |ene90PointsForma|
00000130 74 4d 65 74 61 00 00 00 00 6b f0 66 56 c3 12 5b |tMeta....k.fV..[|
00000140 07 08 12 3a 32 4d 4b 92 f8 00 01 00 00 00 3f d7 |...:2MK.......?.|
00000150 6c 17 03 42 4b 44 00 00 00 09 01 01 80 04 08 01 |l..BKD..........|
00000160 80 00 01 81 b4 f6 00 0f 80 00 01 81 b5 2b 3d 9d |.............+=.|
00000170 07 07 01 32 00 00 00 00 00 00 00 33 00 00 00 00 |...2.......3....|
00000180 00 00 00 ff ff ff ff 44 00 00 00 00 00 00 00 72 |.......D.......r|
00000190 00 00 00 00 00 00 00 c0 28 93 e8 00 00 00 00 00 |........(.......|
000001a0 00 00 00 09 71 1c 79 00 3f d7 6c 17 12 42 6c 6f |....q.y.?.l..Blo|
000001b0 63 6b 54 72 65 65 54 65 72 6d 73 4d 65 74 61 00 |ckTreeTermsMeta.|
000001c0 00 00 00 6b f0 66 56 c3 12 5b 07 08 12 3a 32 4d |...k.fV..[...:2M|
000001d0 4b 92 f8 0a 4c 75 63 65 6e 65 39 30 5f 30 3f d7 |K...Lucene90_0?.|
000001e0 6c 17 1b 4c 75 63 65 6e 65 39 30 50 6f 73 74 69 |l..Lucene90Posti|
000001f0 6e 67 73 57 72 69 74 65 72 54 65 72 6d 73 00 00 |ngsWriterTerms..|
00000200 00 00 6b f0 66 56 c3 12 5b 07 08 12 3a 32 4d 4b |..k.fV..[...:2MK|
00000210 92 f8 0a 4c 75 63 65 6e 65 39 30 5f 30 80 01 02 |...Lucene90_0...|
00000220 02 8c 01 0c db 01 03 62 af 05 67 cf 09 6d 95 14 |.......b..g..m..|
00000230 c2 02 a5 01 06 01 30 03 cd b1 69 37 3f d7 6c 17 |......0...i7?.l.|
00000240 03 46 53 54 00 00 00 08 01 0d 14 95 6d 09 cf 67 |.FST........m..g|
00000250 05 af 62 03 01 db 0c 00 00 01 00 07 02 a2 37 07 |..b...........7.|
00000260 07 16 2f 68 6f 6d 65 2f 64 61 69 2f 64 6f 63 73 |../home/dai/docs|
00000270 2f 61 61 61 2e 74 78 74 1f 2f 68 6f 6d 65 2f 64 |/aaa.txt./home/d|
00000280 61 69 2f 64 6f 63 73 2f 69 6e 64 65 78 2f 77 72 |ai/docs/index/wr|
00000290 69 74 65 2e 6c 6f 63 6b 38 3f d7 6c 17 03 46 53 |ite.lock8?.l..FS|
000002a0 54 00 00 00 08 01 03 37 a2 02 00 00 01 49 00 00 |T......7.....I..|
000002b0 00 00 00 00 00 c9 07 00 00 00 00 00 00 c0 28 93 |..............(.|
000002c0 e8 00 00 00 00 00 00 00 00 c1 1b ff e4 00 00 00 |................|
000002d0 3f d7 6c 17 18 4c 75 63 65 6e 65 39 30 50 6f 69 |?.l..Lucene90Poi|
000002e0 6e 74 73 46 6f 72 6d 61 74 44 61 74 61 00 00 00 |ntsFormatData...|
000002f0 00 6b f0 66 56 c3 12 5b 07 08 12 3a 32 4d 4b 92 |.k.fV..[...:2MK.|
00000300 f8 00 07 10 00 01 00 06 00 04 00 00 00 05 00 03 |................|
00000310 00 02 00 04 80 00 01 81 00 b4 03 f6 00 0f f6 55 |...............U|
00000320 d3 f8 31 29 b5 04 2b 3d 81 2b 3d 81 2b 3d 85 2b |..1)..+=.+=.+=.+|
00000330 3d 9d c0 28 93 e8 00 00 00 00 00 00 00 00 28 e1 |=..(..........(.|
00000340 c0 de 00 00 00 00 00 00 3f d7 6c 17 19 4c 75 63 |........?.l..Luc|
00000350 65 6e 65 39 30 50 6f 73 74 69 6e 67 73 57 72 69 |ene90PostingsWri|
00000360 74 65 72 50 6f 73 00 00 00 00 6b f0 66 56 c3 12 |terPos....k.fV..|
00000370 5b 07 08 12 3a 32 4d 4b 92 f8 0a 4c 75 63 65 6e |[...:2MK...Lucen|
00000380 65 39 30 5f 30 1e 01 03 b1 01 06 0b 0b a4 01 05 |e90_0...........|
00000390 0d 21 06 02 0b a5 01 0c 0d 0a 0e 19 18 20 09 0b |.!........... ..|
000003a0 5f 19 45 06 30 08 0a 22 02 02 75 51 58 06 0b 03 |_.E.0.."..uQX...|
000003b0 05 03 07 7c 05 23 96 01 02 3c 54 30 37 01 11 18 |...|.#...<T07...|
000003c0 0a 40 30 29 0b 32 92 01 ae 01 03 1f 21 03 88 01 |.@0).2......!...|
000003d0 23 27 d5 01 73 18 0f 5f 07 3a 04 04 06 06 07 06 |#'..s.._.:......|
000003e0 12 19 38 04 00 72 0c 7d 52 3b 04 04 06 06 07 06 |..8..r.}R;......|
000003f0 25 06 38 04 11 46 3e 08 4c 42 11 10 0f 1f bc 01 |%.8..F>.LB......|
00000400 0b 1c 1a 06 8a 01 20 39 04 04 06 06 07 06 12 51 |...... 9.......Q|
00000410 04 c8 01 15 00 7e 44 06 06 07 06 17 06 08 06 04 |.....~D.........|
00000420 38 04 30 30 12 1d 05 07 19 06 05 02 00 05 05 06 |8.00............|
00000430 02 07 0c 05 07 31 05 2a 06 01 06 09 06 06 08 0b |.....1.*........|
00000440 04 00 00 1a 00 1c 0c d1 01 06 2f 07 60 07 15 06 |........../.`...|
00000450 01 01 cb 01 63 1a 26 a8 01 9f 01 13 06 2b 99 01 |....c.&......+..|
00000460 b4 01 01 68 28 09 d4 01 09 1b 0d 6f 0a 16 1b 10 |...h(......o....|
00000470 17 80 01 05 71 cf 01 d0 01 06 d2 01 06 17 1e 04 |....q...........|
00000480 05 0d 07 0c 05 07 31 05 2a 07 06 09 06 06 17 08 |......1.*.......|
00000490 04 04 0c 04 0d 12 2a 01 25 76 0e 07 0f 20 14 1e |......*.%v... ..|
000004a0 53 06 1e 08 a3 01 38 0a 0b a6 01 da 01 03 5e 2b |S.....8.......^+|
000004b0 c5 01 61 18 01 ba 01 38 03 05 0d 07 0c 05 07 31 |..a....8.......1|
000004c0 05 2a 07 06 09 06 06 17 03 04 04 03 03 02 05 0d |.*..............|
000004d0 07 0c 05 07 31 05 2a 07 06 09 06 06 17 02 08 02 |....1.*.........|
000004e0 02 c9 01 c0 28 93 e8 00 00 00 00 00 00 00 00 63 |....(..........c|
000004f0 69 b5 c7 00 00 00 00 00 3f d7 6c 17 15 4c 75 63 |i.......?.l..Luc|
00000500 65 6e 65 39 30 4e 6f 72 6d 73 4d 65 74 61 64 61 |ene90NormsMetada|
00000510 74 61 00 00 00 00 6b f0 66 56 c3 12 5b 07 08 12 |ta....k.fV..[...|
00000520 3a 32 4d 4b 92 f8 00 02 00 00 00 ff ff ff ff ff |:2MK............|
00000530 ff ff ff 00 00 00 00 00 00 00 00 ff ff ff 07 00 |................|
00000540 00 00 01 2b 00 00 00 00 00 00 00 ff ff ff ff c0 |...+............|
00000550 28 93 e8 00 00 00 00 00 00 00 00 72 ba cc 7e 00 |(..........r..~.|
00000560 3f d7 6c 17 12 4c 75 63 65 6e 65 39 30 46 69 65 |?.l..Lucene90Fie|
00000570 6c 64 49 6e 66 6f 73 00 00 00 00 6b f0 66 56 c3 |ldInfos....k.fV.|
00000580 12 5b 07 08 12 3a 32 4d 4b 92 f8 00 03 04 70 61 |.[...:2MK.....pa|
00000590 74 68 00 02 01 00 ff ff ff ff ff ff ff ff 02 1d |th..............|
000005a0 50 65 72 46 69 65 6c 64 50 6f 73 74 69 6e 67 73 |PerFieldPostings|
000005b0 46 6f 72 6d 61 74 2e 66 6f 72 6d 61 74 08 4c 75 |Format.format.Lu|
000005c0 63 65 6e 65 39 30 1d 50 65 72 46 69 65 6c 64 50 |cene90.PerFieldP|
000005d0 6f 73 74 69 6e 67 73 46 6f 72 6d 61 74 2e 73 75 |ostingsFormat.su|
000005e0 66 66 69 78 01 30 00 00 00 08 6d 6f 64 69 66 69 |ffix.0....modifi|
000005f0 65 64 01 00 00 00 ff ff ff ff ff ff ff ff 00 01 |ed..............|
00000600 01 08 00 00 08 63 6f 6e 74 65 6e 74 73 02 00 03 |.....contents...|
00000610 00 ff ff ff ff ff ff ff ff 02 1d 50 65 72 46 69 |...........PerFi|
00000620 65 6c 64 50 6f 73 74 69 6e 67 73 46 6f 72 6d 61 |eldPostingsForma|
00000630 74 2e 66 6f 72 6d 61 74 08 4c 75 63 65 6e 65 39 |t.format.Lucene9|
00000640 30 1d 50 65 72 46 69 65 6c 64 50 6f 73 74 69 6e |0.PerFieldPostin|
00000650 67 73 46 6f 72 6d 61 74 2e 73 75 66 66 69 78 01 |gsFormat.suffix.|
00000660 30 00 00 00 c0 28 93 e8 00 00 00 00 00 00 00 00 |0....(..........|
00000670 1f ee 84 f9 00 00 00 00 3f d7 6c 17 1c 4c 75 63 |........?.l..Luc|
00000680 65 6e 65 39 30 53 74 6f 72 65 64 46 69 65 6c 64 |ene90StoredField|
00000690 73 46 61 73 74 44 61 74 61 00 00 00 01 6b f0 66 |sFastData....k.f|
000006a0 56 c3 12 5b 07 08 12 3a 32 4d 4b 92 f8 00 00 1e |V..[...:2MK.....|
000006b0 00 01 08 18 1d 21 21 1d 1c 18 0a 13 0b 15 12 10 |.....!!.........|
000006c0 15 0f 15 12 10 15 12 a0 00 16 2f 68 6f 6d 65 2f |........../home/|
000006d0 64 61 f0 04 69 2f 64 6f 63 73 2f 62 62 62 2e 74 |da..i/docs/bbb.t|
000006e0 78 74 00 1b 2f 68 6f 01 05 00 e0 69 2f 64 6f 63 |xt../ho....i/doc|
000006f0 73 2f 69 6e 64 65 78 2f 5f 73 30 2e 63 66 73 00 |s/index/_s0.cfs.|
00000700 1f 0f 00 50 61 69 2f 64 6f f0 04 63 73 2f 69 6e |...Pai/do..cs/in|
00000710 64 65 78 2f 73 65 67 6d 65 6e 74 73 5f 31 24 00 |dex/segments_1$.|
00000720 1f 0a 00 90 69 2f 64 6f 63 73 2f 69 6e f0 04 64 |....i/docs/in..d|
00000730 65 78 2f 77 72 69 74 65 2e 6c 6f 63 6b 00 1b 2f |ex/write.lock../|
00000740 68 6f 01 05 00 e0 69 2f 64 6f 63 73 2f 69 6e 64 |ho....i/docs/ind|
00000750 65 78 2f 5f 73 30 2e 63 66 65 00 1a 0f 00 50 61 |ex/_s0.cfe....Pa|
00000760 69 2f 64 6f f0 04 63 73 2f 69 6e 64 65 78 2f 5f |i/do..cs/index/_|
00000770 30 2e 73 69 00 16 2f 68 6f 01 05 00 e0 69 2f 64 |0.si../ho....i/d|
00000780 6f 63 73 2f 61 61 61 2e 74 78 74 c0 28 93 e8 00 |ocs/aaa.txt.(...|
00000790 00 00 00 00 00 00 00 52 80 f1 02 00 00 00 00 00 |.......R........|
000007a0 3f d7 6c 17 13 42 6c 6f 63 6b 54 72 65 65 54 65 |?.l..BlockTreeTe|
000007b0 72 6d 73 49 6e 64 65 78 00 00 00 00 6b f0 66 56 |rmsIndex....k.fV|
000007c0 c3 12 5b 07 08 12 3a 32 4d 4b 92 f8 0a 4c 75 63 |..[...:2MK...Luc|
000007d0 65 6e 65 39 30 5f 30 00 00 c0 28 93 e8 00 00 00 |ene90_0...(.....|
000007e0 00 00 00 00 00 6e c7 b4 6e 00 00 00 00 00 00 00 |.....n..n.......|
000007f0 3f d7 6c 17 11 4c 75 63 65 6e 65 39 30 4e 6f 72 |?.l..Lucene90Nor|
00000800 6d 73 44 61 74 61 00 00 00 00 6b f0 66 56 c3 12 |msData....k.fV..|
00000810 5b 07 08 12 3a 32 4d 4b 92 f8 00 08 44 0e 00 21 |[...:2MK....D..!| <------------- here 08 44 0e 00 21
00000820 29 04 c0 28 93 e8 00 00 00 00 00 00 00 00 43 ab |)..(..........C.| <------------ 04 就是norm
00000830 9e 6c 00 00 00 00 00 00 3f d7 6c 17 19 4c 75 63 |.l......?.l..Luc|
00000840 65 6e 65 39 30 50 6f 73 74 69 6e 67 73 57 72 69 |ene90PostingsWri|
00000850 74 65 72 44 6f 63 00 00 00 00 6b f0 66 56 c3 12 |terDoc....k.fV..|
00000860 5b 07 08 12 3a 32 4d 4b 92 f8 0a 4c 75 63 65 6e |[...:2MK...Lucen|
00000870 65 39 30 5f 30 03 03 02 05 08 03 01 02 02 0b 03 |e90_0...........|
00000880 07 02 02 07 01 03 02 02 07 02 02 07 03 07 03 07 |................|
00000890 05 02 15 03 04 02 03 02 10 03 05 03 05 05 02 10 |................|
000008a0 02 03 05 03 02 10 02 02 05 03 c0 28 93 e8 00 00 |...........(....|
000008b0 00 00 00 00 00 00 8d fa 92 14 00 00 00 00 00 00 |................|
000008c0 3f d7 6c 17 12 42 6c 6f 63 6b 54 72 65 65 54 65 |?.l..BlockTreeTe|
000008d0 72 6d 73 44 69 63 74 00 00 00 00 6b f0 66 56 c3 |rmsDict....k.fV.|
000008e0 12 5b 07 08 12 3a 32 4d 4b 92 f8 0a 4c 75 63 65 |.[...:2MK...Luce|
000008f0 6e 65 39 30 5f 30 36 84 0e 30 30 75 62 75 6e 74 |ne90_06..00ubunt|
00000900 75 30 2e 32 32 2e 30 34 2e 31 31 31 30 2e 30 2e |u0.22.04.1110.0.|
00000910 30 31 36 35 36 36 30 31 39 31 38 38 33 36 31 37 |0165660191883617|
00000920 2e 30 2e 33 31 65 31 69 31 6d 31 6d 31 6d 32 33 |.0.31e1i1m1m1m23|
00000930 33 33 35 2e 31 35 2e 30 36 37 39 5f 30 5f 30 5f |335.15.0679_0_0_|
00000940 6c 75 63 65 6e 65 39 30 66 69 65 6c 64 5f 30 5f |lucene90field_0_|
00000950 6c 75 63 65 6e 65 39 30 66 69 65 6c 64 73 69 6e |lucene90fieldsin|
00000960 64 65 78 5f 30 5f 6c 75 63 65 6e 65 39 30 66 69 |dex_0_lucene90fi|
00000970 65 6c 64 73 69 6e 64 65 78 66 69 6c 65 5f 70 6f |eldsindexfile_po|
00000980 69 6e 74 65 72 73 5f 31 5f 30 cb b9 5f 6c 75 63 |inters_1_0.._luc|
00000990 65 6e 65 39 30 5f 30 5f 6c 75 63 65 6e 65 39 30 |ene90_0_lucene90|
000009a0 66 69 65 6c 64 73 69 6e 64 65 78 61 61 61 61 2e |fieldsindexaaaa.|
000009b0 74 78 74 61 61 6d 62 6f 79 64 6f 67 6f 6f 64 69 |txtaamboydogoodi|
000009c0 69 73 6b 6e 6f 77 74 68 69 6e 67 77 68 61 74 79 |isknowthingwhaty|
000009d0 6f 75 61 6d 61 6d 64 36 34 36 01 10 01 06 0d 06 |ouamamd646......|
000009e0 08 02 01 01 02 06 01 01 01 02 10 16 25 04 0b 14 |............%...|
000009f0 01 07 1f 02 05 1c 02 04 02 01 04 00 03 02 02 03 |................|
00000a00 02 01 07 02 01 02 01 04 06 07 02 04 01 06 01 02 |................|
00000a10 02 05 3a 7a 01 3d 11 06 00 02 04 05 03 01 01 01 |..:z.=..........|
00000a20 01 0f 03 01 02 01 01 01 02 11 01 01 01 0f 01 11 |................|
00000a30 01 0f 02 00 02 08 01 08 01 01 01 01 05 01 09 01 |................|
00000a40 0b 05 00 01 08 01 05 01 03 15 01 03 01 38 b4 09 |.............8..|
00000a50 62 62 62 62 2e 74 78 74 62 65 73 74 5f 73 70 65 |bbbb.txtbest_spe|
00000a60 65 64 62 6b 64 62 6c 6f 63 6b 74 72 65 65 74 65 |edbkdblocktreete|
00000a70 72 6d 73 64 69 63 74 62 6c 6f 63 6b 74 72 65 65 |rmsdictblocktree|
00000a80 74 65 72 6d 73 69 6e 64 65 78 62 6c 6f 63 6b 74 |termsindexblockt|
00000a90 72 65 65 74 65 72 6d 73 6d 65 74 61 62 6f 79 62 |reetermsmetaboyb|
00000aa0 75 69 6c 64 63 63 66 65 63 66 73 63 6f 6e 74 65 |uildccfecfsconte|
00000ab0 6e 74 73 63 73 64 64 61 69 64 6f 64 6f 63 64 6f |ntscsddaidodocdo|
00000ac0 63 5f 64 6f 63 5f 69 64 73 5f 30 64 6f 63 73 65 |c_doc_ids_0docse|
00000ad0 75 66 66 64 6d 66 64 74 66 64 78 66 6c 75 73 68 |uffdmfdtfdxflush|
00000ae0 66 6e 6d 66 73 74 38 01 07 0a 03 12 13 12 03 05 |fnmfst8.........|
00000af0 01 03 03 08 02 01 03 02 03 04 09 04 03 03 03 03 |................|
00000b00 05 03 03 1b 04 00 02 01 0d 02 02 05 02 01 04 01 |................|
00000b10 02 0a 04 00 05 02 0a 01 04 01 04 01 05 02 01 3d |...............=|
00000b20 8e 01 77 04 01 02 11 02 0f 01 01 01 01 01 01 02 |..w.............|
00000b30 15 02 03 01 0f 01 11 04 01 01 0f 01 01 02 00 02 |................|
00000b40 06 01 03 00 0b 04 04 02 0b 01 01 01 01 01 01 0b |................|
00000b50 00 01 06 03 06 04 03 05 01 03 01 0b 01 50 cc 20 |.............P. |
00000b60 67 67 65 6e 65 72 69 63 67 6f 6f 64 68 68 6f 6d |ggenericgoodhhom|
00000b70 65 69 69 64 73 5f 30 69 6e 64 65 78 69 73 6a 6a |eiids_0indexisjj|
00000b80 61 76 61 2e 72 75 6e 74 69 6d 65 2e 76 65 72 73 |ava.runtime.vers|
00000b90 69 6f 6e 6a 61 76 61 2e 76 65 6e 64 6f 72 6a 61 |ionjava.vendorja|
00000ba0 76 61 2e 76 65 72 73 69 6f 6e 6a 61 76 61 2e 76 |va.versionjava.v|
00000bb0 6d 2e 76 65 72 73 69 6f 6e 6b 64 64 6b 64 69 6b |m.versionkddkdik|
00000bc0 64 6d 30 6b 6e 6f 77 6c 6c 69 6e 75 78 6c 75 63 |dm0knowllinuxluc|
00000bd0 65 6e 65 2e 76 65 72 73 69 6f 6e 6c 75 63 65 6e |ene.versionlucen|
00000be0 65 39 30 6c 75 63 65 6e 65 39 30 5f 30 6c 75 63 |e90lucene90_0luc|
00000bf0 65 6e 65 39 30 63 6f 6d 70 6f 75 6e 64 64 61 74 |ene90compounddat|
00000c00 61 6c 75 63 65 6e 65 39 30 63 6f 6d 70 6f 75 6e |alucene90compoun|
00000c10 64 65 6e 74 72 69 65 73 6c 75 63 65 6e 65 39 30 |dentrieslucene90|
00000c20 66 69 65 6c 64 69 6e 66 6f 73 6c 75 63 65 6e 65 |fieldinfoslucene|
00000c30 39 30 66 69 65 6c 64 73 69 6e 64 65 78 69 64 78 |90fieldsindexidx|
00000c40 6c 75 63 65 6e 65 39 30 66 69 65 6c 64 73 69 6e |lucene90fieldsin|
00000c50 64 65 78 6d 65 74 61 6c 75 63 65 6e 65 39 30 6e |dexmetalucene90n|
00000c60 6f 72 6d 73 64 61 74 61 6c 75 63 65 6e 65 39 30 |ormsdatalucene90|
00000c70 6e 6f 72 6d 73 6d 65 74 61 64 61 74 61 6c 75 63 |normsmetadataluc|
00000c80 65 6e 65 39 30 70 6f 69 6e 74 73 66 6f 72 6d 61 |ene90pointsforma|
00000c90 74 64 61 74 61 6c 75 63 65 6e 65 39 30 70 6f 69 |tdatalucene90poi|
00000ca0 6e 74 73 66 6f 72 6d 61 74 69 6e 64 65 78 6c 75 |ntsformatindexlu|
00000cb0 63 65 6e 65 39 30 70 6f 69 6e 74 73 66 6f 72 6d |cene90pointsform|
00000cc0 61 74 6d 65 74 61 6c 75 63 65 6e 65 39 30 70 6f |atmetalucene90po|
00000cd0 73 74 69 6e 67 73 77 72 69 74 65 72 64 6f 63 6c |stingswriterdocl|
00000ce0 75 63 65 6e 65 39 30 70 6f 73 74 69 6e 67 73 77 |ucene90postingsw|
00000cf0 72 69 74 65 72 70 6f 73 6c 75 63 65 6e 65 39 30 |riterposlucene90|
00000d00 70 6f 73 74 69 6e 67 73 77 72 69 74 65 72 74 65 |postingswriterte|
00000d10 72 6d 73 6c 75 63 65 6e 65 39 30 73 65 67 6d 65 |rmslucene90segme|
00000d20 6e 74 69 6e 66 6f 6c 75 63 65 6e 65 39 30 73 74 |ntinfolucene90st|
00000d30 6f 72 65 64 66 69 65 6c 64 73 66 61 73 74 64 61 |oredfieldsfastda|
00000d40 74 61 6c 75 63 65 6e 65 39 30 73 74 6f 72 65 64 |talucene90stored|
00000d50 66 69 65 6c 64 73 66 6f 72 6d 61 74 2e 6d 6f 64 |fieldsformat.mod|
00000d60 65 6c 75 63 65 6e 65 39 33 50 01 07 04 01 04 01 |elucene93P......|
00000d70 05 05 02 01 14 0b 0c 0f 03 03 04 04 01 05 0e 08 |................|
00000d80 0a 14 17 12 16 17 11 15 18 19 18 19 19 1b 13 1c |................|
00000d90 1f 08 16 05 04 00 02 09 06 00 01 02 0a 01 02 01 |................|
00000da0 0f 08 15 03 02 01 02 05 21 56 a8 01 04 b9 01 05 |........!V......|
00000db0 01 13 01 00 01 04 01 03 00 0a 06 01 04 01 01 03 |................|
00000dc0 0b 05 01 11 02 01 01 01 01 01 01 03 01 01 01 01 |................|
00000dd0 01 0f 01 00 01 0c 05 19 01 01 0f 01 01 03 01 06 |................|
00000de0 0d 01 0b 01 01 02 01 01 01 01 01 01 01 02 01 02 |................|
00000df0 01 01 01 01 01 01 01 02 11 02 0f 01 11 01 0b 01 |................|
00000e00 5b a4 0f 6d 6f 64 69 66 69 65 64 6e 76 64 6e 76 |[..modifiednvdnv|
00000e10 6d 6f 6f 63 73 6f 73 6f 73 2e 61 72 63 68 6f 73 |moocsosos.archos|
00000e20 2e 76 65 72 73 69 6f 6e 70 70 61 69 70 61 74 68 |.versionppaipath|
00000e30 70 65 72 66 69 65 6c 64 70 6f 73 74 69 6e 67 73 |perfieldpostings|
00000e40 66 6f 72 6d 61 74 2e 66 6f 72 6d 61 74 70 65 72 |format.formatper|
00000e50 66 69 65 6c 64 70 6f 73 74 69 6e 67 73 66 6f 72 |fieldpostingsfor|
00000e60 6d 61 74 2e 73 75 66 66 69 78 70 6f 73 70 72 69 |mat.suffixpospri|
00000e70 76 61 74 65 70 d7 99 70 d7 9b 70 d7 9c 71 71 78 |vatep..p..p..qqx|
00000e80 72 73 65 67 6d 65 6e 74 73 73 69 73 69 6e 64 65 |rsegmentssisinde|
00000e90 78 66 69 6c 65 5f 70 6f 69 6e 74 65 72 73 5f 31 |xfile_pointers_1|
00000ea0 73 6f 75 72 63 65 74 68 69 6e 67 74 69 6d 74 69 |sourcethingtimti|
00000eb0 6d 65 73 74 61 6d 70 74 69 70 78 74 6d 64 74 6d |mestamptipxtmdtm|
00000ec0 70 75 75 62 75 6e 74 75 76 78 77 63 77 68 61 74 |puubuntuvxwcwhat|
00000ed0 77 72 69 74 65 2e 6c 6f 63 6b 77 72 69 74 65 2e |write.lockwrite.|
00000ee0 6c 6f 63 6b 38 78 79 79 6f 75 79 6f 75 37 7a 7a |lock8xyyouyou7zz|
00000ef0 74 37 cb b9 cd b1 69 5a 08 03 03 01 03 02 07 0a |t7....iZ........|
00000f00 01 03 04 1d 1d 03 07 03 03 03 01 03 08 02 15 06 |................|
00000f10 05 03 09 04 03 03 01 06 02 02 04 0a 0b 01 01 03 |................|
00000f20 04 01 03 02 03 21 07 02 02 05 02 01 03 02 01 02 |.....!..........|
00000f30 01 03 08 0f 03 04 00 13 02 03 02 01 02 01 05 02 |................|
00000f40 01 0b 08 11 08 10 01 60 be 01 01 9e 02 0d 02 01 |.......`........|
00000f50 01 01 01 0b 01 11 03 01 01 01 01 0f 01 01 03 01 |................|
00000f60 01 01 02 01 03 0d 03 05 01 00 01 0a 02 13 01 01 |................|
00000f70 00 01 04 05 02 0b 01 0d 01 0f 01 11 01 13 01 11 |................|
00000f80 01 05 01 03 01 01 01 0b 01 01 04 11 03 0f 02 01 |................|
00000f90 02 03 02 05 01 01 02 01 02 0d 01 0f 01 05 01 01 |................|
00000fa0 02 00 01 0c 15 0c 01 14 0f d4 0b 2f 68 6f 6d 65 |.........../home|
00000fb0 2f 64 61 69 2f 64 6f 63 73 2f 61 61 61 2e 74 78 |/dai/docs/aaa.tx|
00000fc0 74 2f 68 6f 6d 65 2f 64 61 69 2f 64 6f 63 73 2f |t/home/dai/docs/|
00000fd0 62 62 62 2e 74 78 74 2f 68 6f 6d 65 2f 64 61 69 |bbb.txt/home/dai|
00000fe0 2f 64 6f 63 73 2f 69 6e 64 65 78 2f 5f 30 2e 63 |/docs/index/_0.c|
00000ff0 66 65 2f 68 6f 6d 65 2f 64 61 69 2f 64 6f 63 73 |fe/home/dai/docs|
00001000 2f 69 6e 64 65 78 2f 5f 30 2e 63 66 73 2f 68 6f |/index/_0.cfs/ho|
00001010 6d 65 2f 64 61 69 2f 64 6f 63 73 2f 69 6e 64 65 |me/dai/docs/inde|
00001020 78 2f 5f 30 2e 73 69 2f 68 6f 6d 65 2f 64 61 69 |x/_0.si/home/dai|
00001030 2f 64 6f 63 73 2f 69 6e 64 65 78 2f 73 65 67 6d |/docs/index/segm|
00001040 65 6e 74 73 5f 31 2f 68 6f 6d 65 2f 64 61 69 2f |ents_1/home/dai/|
00001050 64 6f 63 73 2f 69 6e 64 65 78 2f 77 72 69 74 65 |docs/index/write|
00001060 2e 6c 6f 63 6b 0e 16 16 1b 1b 1a 1f 1f 01 0d 09 |.lock...........|
00001070 e4 01 06 17 11 0b 11 0b 05 c0 28 93 e8 00 00 00 |..........(.....|
00001080 00 00 00 00 00 26 7d 6b cb 00 00 00 00 00 00 00 |.....&}k........|
00001090 3f d7 6c 17 16 4c 75 63 65 6e 65 39 30 46 69 65 |?.l..Lucene90Fie|
000010a0 6c 64 73 49 6e 64 65 78 49 64 78 00 00 00 00 6b |ldsIndexIdx....k|
000010b0 f0 66 56 c3 12 5b 07 08 12 3a 32 4d 4b 92 f8 00 |.fV..[...:2MK...|
000010c0 c0 28 93 e8 00 00 00 00 00 00 00 00 be 7c 21 a1 |.(...........|!.|
000010d0 c0 28 93 e8 00 00 00 00 00 00 00 00 15 f4 63 e8 |.(............c.|
000010e0

gdb 读取内容:

(gdb) x/32xb 140063879776283
0x7f6329ccc81b: 0x08 0x44 0x0e 0x00 0x21 0x29 0x04 0xc0
0x7f6329ccc823: 0x28 0x93 0xe8 0x00 0x00 0x00 0x00 0x00
0x7f6329ccc82b: 0x00 0x00 0x00 0x43 0xab 0x9e 0x6c 0x00
0x7f6329ccc833: 0x00 0x00 0x00 0x00 0x00 0x3f 0xd7 0x6c

源码分析

DirectByteBufferR 继承关系

DirectByteBufferR extend

依赖以下的脚本自动根据平台自动实现nio的DirectByteBufferR这个类:

// 源码地址 jdk/make/modules/java.base/gensrc/GensrcBuffer.gmk
# Direct byte buffer
#
DIRECT_X_BUF := Direct-X-Buffer

$(eval $(call SetupGenBuffer,DirectByteBuffer, $(DIRECT_X_BUF), type:=byte, BIN:=1))
$(eval $(call SetupGenBuffer,DirectByteBufferR,$(DIRECT_X_BUF), type:=byte, BIN:=1, RW:=R))

DirectByteBufferR 继承 DirectByteBuffer , DirectByteBuffer 则继承ByteBuffer
下面是编译后通过宏自动构建的DirectByteBufferR类,需要编译jvm的时候才能生成,我的在这个目录生成(编译jdk之后才会有这个文件,直接下载是没有这个文件的) jdk/build/linux-x86_64-server-slowdebug/support/gensrc/java.base/java/nio/DirectByteBufferR.java



// -- This file was mechanically generated: Do not edit! -- //

package java.nio;

import java.io.FileDescriptor;
import java.lang.ref.Reference;
import java.util.Objects;
import jdk.internal.access.foreign.MemorySegmentProxy;
import jdk.internal.misc.ScopedMemoryAccess.Scope;
import jdk.internal.misc.VM;
import jdk.internal.ref.Cleaner;
import sun.nio.ch.DirectBuffer;


class DirectByteBufferR extends DirectByteBuffer implements DirectBuffer
{
...
// Primary constructor
//
DirectByteBufferR(int cap) { // package-private
super(cap);
this.isReadOnly = true;

}



// For memory-mapped buffers -- invoked by FileChannelImpl via reflection
//
protected DirectByteBufferR(int cap, long addr,
FileDescriptor fd,
Runnable unmapper,
boolean isSync, MemorySegmentProxy segment)
{
super(cap, addr, fd, unmapper, isSync, segment);
this.isReadOnly = true;
}

...

}

他的读取方法DirectByteBufferR.get是从DirectByteBuffer继承的,下面是实现:

实际是调用SCOPED_MEMORY_ACCESS.getByte

// jdk/build/linux-x86_64-server-slowdebug/support/gensrc/java.base/java/nio/DirectByteBuffer.java
public byte get() {
try {
return ((SCOPED_MEMORY_ACCESS.getByte(scope(), null, ix(nextGetIndex()))));
} finally {
Reference.reachabilityFence(this);
}
}

public byte get(int i) {
try {
return ((SCOPED_MEMORY_ACCESS.getByte(scope(), null, ix(checkIndex(i)))));
} finally {
Reference.reachabilityFence(this);
}
}

SCOPED_MEMORY_ACCESS是在MappedByteBuffer里面定义的 ,而DirectByteBufferMappedByteBuffer 子类

class DirectByteBuffer  extends MappedByteBuffer implements DirectBuffer
{
...
}

SCOPED_MEMORY_ACCESS.getByte最后调用的是UNSAFE.getByte


public class ScopedMemoryAccess {

private static final Unsafe UNSAFE = Unsafe.getUnsafe();


@ForceInline
public byte getByte(Scope scope, Object base, long offset) {
...
return getByteInternal(scope, base, offset); // 调用 内部函数
...
}

@ForceInline @Scoped
private byte getByteInternal(Scope scope, Object base, long offset) {
...
return UNSAFE.getByte(base, offset); // 最后调用的是UNSAFE.getByte
...
}

UNSAFE是一个全局的静态变量,最后调用的是

// jdk/src/hotspot/share/prims/unsafe.cpp

UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
return MemoryAccess<java_type>(thread, obj, offset).get(); \
} UNSAFE_END \

展开之后是调用MemoryAccess的get方法,实际是获取内存的值

相关阅读

java 基本类型

· One min read

背景

了解java的基本类型,基本类型的大小和取值范围

platform:amd64

源码分析

在c++ standard 里面

类型是否有符号最小范围字节数type
charimplement defined [Type char is a distinct type that has an implementation-defined choice of “signed char” or “unsigned char” as its underlying type]--
signed charsigned--signed type
short intsigned--signed type
intsigned--signed type
long intsigned--signed type
long long intsigned--signed type

在linux 64位下面

java基本类型c/c++宏
jintint
jlonglong
jbytesigned char
jbooleanunsigned char
jcharunsigned short
jfloatfloat
jdoubledouble
jsizejint 也就是int
// jdk/src/java.base/unix/native/include/jni_md.h
typedef int jint;
#ifdef _LP64
typedef long jlong;
#else
typedef long long jlong;
#endif

typedef signed char jbyte;
// jdk/src/java.base/share/native/include/jni.h
#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H

typedef unsigned char jboolean;
typedef unsigned short jchar;
typedef short jshort;
typedef float jfloat;
typedef double jdouble;

typedef jint jsize;

相关阅读