Skip to main content

100 posts tagged with "java"

View All Tags

java volatile

· 5 min read

背景

了解java的volaite 内容

volatile

volatile 在jls有几个描述:

  • keyword
  • filed modified

volatile目的

volatile详细描述在: 8.3.1.4 volatile Fields

The Java programming language allows threads to access shared variables (§17.1).
As a rule, to ensure that shared variables are consistently and reliably updated, a
thread should ensure that it has exclusive use of such variables by obtaining a lock
that, conventionally, enforces mutual exclusion for those shared variables.
The Java programming language provides a second mechanism, volatile fields,
that is more convenient than locking for some purposes

翻译:

在java中,可以由不同的线程共享一个变量.
线程必须通过获得锁来保证共享的变量可以被可靠和一致的更新.
简单来说,就是使用mutual的排他性来获取这个特性
java除了通过锁,还有另外一个机制来访问和更新共享变量,这就是volatile fields.
在某些情况下volatile field会比锁更加方便

visibility, ordering and atomicity

同步有三个问题:

  • 可见性
  • 排序
  • 原子性

jsr-133 里面有三个不正常同步会出现的问题 ,原文如下:

If a program is not correctly synchronized, then three types of problems can appear:
visibility, ordering and atomicity.

orderging

下面是jsr133 里面给的例子:

分别有两个线程: threadOne 和线程threadTwo

class BadlyOrdered {
boolean a = false;
boolean b = false;

void threadOne() {
a = true;
b = true;
}

boolean threadTwo() {
boolean r1 = b; // sees true
boolean r2 = a; // sees false
return r1 && !r2; // returns true
}
}

在网上找了个c++ 版本的cpu指令重排的例子来源

命名为 reorder.cpp

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>

// Set either of these to 1 to prevent CPU reordering
#define USE_CPU_FENCE 0
#define USE_SINGLE_HW_THREAD 0 // Supported on Linux, but not Cygwin or PS3

#if USE_SINGLE_HW_THREAD
#include <sched.h>
#endif


//-------------------------------------
// MersenneTwister
// A thread-safe random number generator with good randomness
// in a small number of instructions. We'll use it to introduce
// random timing delays.
//-------------------------------------
#define MT_IA 397
#define MT_LEN 624

class MersenneTwister
{
unsigned int m_buffer[MT_LEN];
int m_index;

public:
MersenneTwister(unsigned int seed);
// Declare noinline so that the function call acts as a compiler barrier:
unsigned int integer() __attribute__((noinline));
};

MersenneTwister::MersenneTwister(unsigned int seed)
{
// Initialize by filling with the seed, then iterating
// the algorithm a bunch of times to shuffle things up.
for (int i = 0; i < MT_LEN; i++)
m_buffer[i] = seed;
m_index = 0;
for (int i = 0; i < MT_LEN * 100; i++)
integer();
}

unsigned int MersenneTwister::integer()
{
// Indices
int i = m_index;
int i2 = m_index + 1; if (i2 >= MT_LEN) i2 = 0; // wrap-around
int j = m_index + MT_IA; if (j >= MT_LEN) j -= MT_LEN; // wrap-around

// Twist
unsigned int s = (m_buffer[i] & 0x80000000) | (m_buffer[i2] & 0x7fffffff);
unsigned int r = m_buffer[j] ^ (s >> 1) ^ ((s & 1) * 0x9908B0DF);
m_buffer[m_index] = r;
m_index = i2;

// Swizzle
r ^= (r >> 11);
r ^= (r << 7) & 0x9d2c5680UL;
r ^= (r << 15) & 0xefc60000UL;
r ^= (r >> 18);
return r;
}


//-------------------------------------
// Main program, as decribed in the post
//-------------------------------------
sem_t beginSema1;
sem_t beginSema2;
sem_t endSema;

int X, Y;
int r1, r2;

void *thread1Func(void *param)
{
MersenneTwister random(1);
for (;;)
{
sem_wait(&beginSema1); // Wait for signal
while (random.integer() % 8 != 0) {} // Random delay

// ----- THE TRANSACTION! -----
X = 1;
#if USE_CPU_FENCE
asm volatile("mfence" ::: "memory"); // Prevent CPU reordering
#else
asm volatile("" ::: "memory"); // Prevent compiler reordering
#endif
r1 = Y;

sem_post(&endSema); // Notify transaction complete
}
return NULL; // Never returns
};

void *thread2Func(void *param)
{
MersenneTwister random(2);
for (;;)
{
sem_wait(&beginSema2); // Wait for signal
while (random.integer() % 8 != 0) {} // Random delay

// ----- THE TRANSACTION! -----
Y = 1;
#if USE_CPU_FENCE
asm volatile("mfence" ::: "memory"); // Prevent CPU reordering
#else
asm volatile("" ::: "memory"); // Prevent compiler reordering
#endif
r2 = X;

sem_post(&endSema); // Notify transaction complete
}
return NULL; // Never returns
};

int main()
{
// Initialize the semaphores
sem_init(&beginSema1, 0, 0);
sem_init(&beginSema2, 0, 0);
sem_init(&endSema, 0, 0);

// Spawn the threads
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, thread1Func, NULL);
pthread_create(&thread2, NULL, thread2Func, NULL);

#if USE_SINGLE_HW_THREAD
// Force thread affinities to the same cpu core.
cpu_set_t cpus;
CPU_ZERO(&cpus);
CPU_SET(0, &cpus);
pthread_setaffinity_np(thread1, sizeof(cpu_set_t), &cpus);
pthread_setaffinity_np(thread2, sizeof(cpu_set_t), &cpus);
#endif

// Repeat the experiment ad infinitum
int detected = 0;
for (int iterations = 1; ; iterations++)
{
// Reset X and Y
X = 0;
Y = 0;
// Signal both threads
sem_post(&beginSema1);
sem_post(&beginSema2);
// Wait for both threads
sem_wait(&endSema);
sem_wait(&endSema);
// Check if there was a simultaneous reorder
if (r1 == 0 && r2 == 0)
{
detected++;
printf("%d reorders detected after %d iterations\n", detected, iterations);
}
}
return 0; // Never returns
}

## 然后编译
gcc -O2 reorder.cpp -o reorder

## 执行
./reorder

相关阅读

java 方法签名

· One min read

背景

了解java的签名相关内容

javap 查看签名

javap -s java.lang.String
Compiled from "String.java"
public final class java.lang.String implements java.io.Serializable, java.lang.Comparable<java.lang.String>, java.lang.CharSequence {
static final boolean COMPACT_STRINGS;
descriptor: Z
public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
descriptor: Ljava/util/Comparator;
static final byte LATIN1;
descriptor: B
static final byte UTF16;
descriptor: B
public java.lang.String();
descriptor: ()V



public java.lang.String(byte[], int, int, int);
descriptor: ([BIII)V

public java.lang.String(byte[], int);
descriptor: ([BI)V

public java.lang.String(byte[], int, int, java.lang.String) throws java.io.UnsupportedEncodingException;
descriptor: ([BIILjava/lang/String;)V


}

相关阅读

tomcat 编译

· 4 min read

背景

了解tomcat生命周期,了解一个http的生命周期

步骤

  • 1 拉取tomcat 代码
git clone https://github.com/apache/tomcat

相关的编译后的安装目录在${tomcat.source}/build.propertiesfile 里面

  • 2 安装ant

我的是ubuntu所以直接通过包管理安装

sudo apt install ant

  • 3 修改复制build.properties 文件 这里面会有相关的属性,和下载代码相关的路径需要在这里配置
cp build.properties.default  build.properties


我们需要将调试符号编译时生成,如果是一个java程序,则是javac -g , 也就是在编译的时候添加到javac 中. 在tomcat的源代码中的build.xml 中很容易看到compile.debug 这个环境变量

<javac srcdir="java" destdir="${tomcat.classes}"
debug="${compile.debug}" <--! 这里会有compile.debug 环境变量 ->
deprecation="${compile.deprecation}"
release="${compile.release}"
encoding="ISO-8859-1"
includeAntRuntime="true" >
<!-- Uncomment this to show unchecked warnings:
<compilerarg value="-Xlint:unchecked"/>

那么这个环境变量是在哪里控制的呢? 打开 build.properties ,就能看到,所以默认下载下来的tomcat 就是开了-g 选项的,不需要修改

# ----- Build control flags -----
compile.debug=true
  • 4 执行构建命令ant
ant

编译好的相关代码会在 , source_code 就是你的源代码

{source_code}/output/build/bin

切换目录到{source_code}/output/build/bin

./startup.sh 
Using CATALINA_BASE: /home/dai/tomcat/output/build
Using CATALINA_HOME: /home/dai/tomcat/output/build
Using CATALINA_TMPDIR: /home/dai/tomcat/output/build/temp
Using JRE_HOME: /usr
Using CLASSPATH: /home/dai/tomcat/output/build/bin/bootstrap.jar:/home/dai/tomcat/output/build/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.

查看tomcat 的命令 , 就是以下内容:

ps aux | grep tomcat


/usr/bin/java -Djava.util.logging.config.file=/home/dai/tomcat/output/build/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -classpath /home/dai/tomcat/output/build/bin/bootstrap.jar:/home/dai/tomcat/output/build/bin/tomcat-juli.jar -Dcatalina.base=/home/dai/tomcat/output/build -Dcatalina.home=/home/dai/tomcat/output/build -Djava.io.tmpdir=/home/dai/tomcat/output/build/temp org.apache.catalina.startup.Bootstrap start


请求tomcat

在浏览器输入 http://127.0.0.1:8080/

debug tomcat

断点到main函数

在上面步骤用ps aux | grep "tomcat" 获取执行的命令 , 然后在前面/usr/bin/java 紧接着的地方加上参数-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 ,让程序断点在main函数

参数说明:

  • suspend 代表是否暂停
  • address: 指定地址 , 也可以只指定端口,我这里是8000 端口
  • -agentlib:jdwp=transport 协议 ,一般本地用socket 通讯 , 也可以共享内存什么的 。 我这里是dt_socket
/usr/bin/java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000   -Djava.util.logging.config.file=/home/dai/tomcat/output/build/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -classpath /home/dai/tomcat/output/build/bin/bootstrap.jar:/home/dai/tomcat/output/build/bin/tomcat-juli.jar -Dcatalina.base=/home/dai/tomcat/output/build -Dcatalina.home=/home/dai/tomcat/output/build -Djava.io.tmpdir=/home/dai/tomcat/output/build/temp org.apache.catalina.startup.Bootstrap start

jdb 开启调试

jdb  -attach  8000 -sourcepath /home/dai/tomcat/java/

### 在 org.apache.catalina.startup.Bootstrap.main 打断点
main[1] stop in org.apache.catalina.startup.Bootstrap.main
Deferring breakpoint org.apache.catalina.startup.Bootstrap.main.
It will be set after the class is loaded.
#### 使用run开始执行
main[1] run

使用list 列出代码 然后就会断点到main 函数

Breakpoint hit: "thread=main", org.apache.catalina.startup.Bootstrap.main(), line=442 bci=0
442 synchronized (daemonLock) {

main[1] list
438 * @param args Command line arguments to be processed
439 */
440 public static void main(String args[]) {
441
442 => synchronized (daemonLock) {
443 if (daemon == null) {
444 // Don't set daemon until init() has completed
445 Bootstrap bootstrap = new Bootstrap();
446 try {
447 bootstrap.init();
main[1]

servelet 请求路径

http-nio-8080-exec-1[1] where
[1] HelloWorldExample.doGet (HelloWorldExample.java:41)
[2] jakarta.servlet.http.HttpServlet.service (HttpServlet.java:705)
[3] jakarta.servlet.http.HttpServlet.service (HttpServlet.java:814)
[4] org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:223)
[5] org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:158)
[6] org.apache.tomcat.websocket.server.WsFilter.doFilter (WsFilter.java:53)
[7] org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:185)
[8] org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:158)
[9] org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter (HttpHeaderSecurityFilter.java:126)
[10] org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:185)
[11] org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:158)
[12] org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:177)
[13] org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:97)
[14] org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:542)
[15] org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:119)
[16] org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:92)
[17] org.apache.catalina.valves.AbstractAccessLogValve.invoke (AbstractAccessLogValve.java:690)
[18] org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:78)
[19] org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:357)
[20] org.apache.coyote.http11.Http11Processor.service (Http11Processor.java:400)
[21] org.apache.coyote.AbstractProcessorLight.process (AbstractProcessorLight.java:65)
[22] org.apache.coyote.AbstractProtocol$ConnectionHandler.process (AbstractProtocol.java:859)
[23] org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun (NioEndpoint.java:1,734)
[24] org.apache.tomcat.util.net.SocketProcessorBase.run (SocketProcessorBase.java:52)
[25] org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1,191)
[26] org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:659)
[27] org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run (TaskThread.java:61)
[28] java.lang.Thread.run (Thread.java:833)

相关阅读

java assert

· One min read

背景

assert 是glibc 一个函数. java也有类似功能,断言是可以快速在测试环境发现问题的功能. 在java里面,assert是一个Statement 也就是一个语句

springboot 请求流程

· 3 min read

背景

了解java里面spring boot 一个http请求的生命周期

tomcat 启动

initialize:108, TomcatWebServer (org.springframework.boot.web.embedded.tomcat)
<init>:104, TomcatWebServer (org.springframework.boot.web.embedded.tomcat)
getTomcatWebServer:440, TomcatServletWebServerFactory (org.springframework.boot.web.embedded.tomcat)
getWebServer:193, TomcatServletWebServerFactory (org.springframework.boot.web.embedded.tomcat)
createWebServer:178, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
onRefresh:158, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:545, AbstractApplicationContext (org.springframework.context.support)
refresh:143, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:755, SpringApplication (org.springframework.boot)
refresh:747, SpringApplication (org.springframework.boot)
refreshContext:402, SpringApplication (org.springframework.boot)
run:312, SpringApplication (org.springframework.boot)
main:22, Application

堆栈:

getLanguagesAllList:35, CommonController (com.patpat.mms.mdp.base.core.rest.controller)
invoke:-1, CommonController$$FastClassBySpringCGLIB$$2cf69542 (com.patpat.mms.mdp.base.core.rest.controller)
invoke:218, MethodProxy (org.springframework.cglib.proxy)
invokeJoinpoint:779, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
proceed:163, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:750, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
proceed:88, MethodInvocationProceedingJoinPoint (org.springframework.aop.aspectj)
doAround:27, AbstractLogAspect (com.patpat.marketing.common.aspect.log)
invoke0:-1, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:62, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:43, DelegatingMethodAccessorImpl (jdk.internal.reflect)
invoke:566, Method (java.lang.reflect)
invokeAdviceMethodWithGivenArgs:644, AbstractAspectJAdvice (org.springframework.aop.aspectj)
invokeAdviceMethod:633, AbstractAspectJAdvice (org.springframework.aop.aspectj)
invoke:70, AspectJAroundAdvice (org.springframework.aop.aspectj)
proceed:186, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:750, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
invoke:95, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:186, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:750, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
intercept:692, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
getLanguagesAllList:-1, CommonController$$EnhancerBySpringCGLIB$$cea69971 (com.patpat.mms.mdp.base.core.rest.controller)
invoke0:-1, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:62, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:43, DelegatingMethodAccessorImpl (jdk.internal.reflect)
invoke:566, Method (java.lang.reflect)
doInvoke:190, InvocableHandlerMethod (org.springframework.web.method.support)
invokeForRequest:138, InvocableHandlerMethod (org.springframework.web.method.support)
invokeAndHandle:105, ServletInvocableHandlerMethod (org.springframework.web.servlet.mvc.method.annotation)
invokeHandlerMethod:878, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handleInternal:792, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handle:87, AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)
doDispatch:1040, DispatcherServlet (org.springframework.web.servlet)
doService:943, DispatcherServlet (org.springframework.web.servlet)
processRequest:1006, 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)

dispatcher servelet

堆栈

doService:911, DispatcherServlet (org.springframework.web.servlet)
processRequest:1006, 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)

相关阅读

javac

· 2 min read

背景

  • 了解java 编译过程
  • 使用java的module调用javac

java的编译命令

在java jdk9 开始,拥有了module 系统 ,jdk里面内部的库也拆分成为不同的module

java的编译前端命令是javac ,实际上调用的是jdk.compiler 这个module下面的类com.sun.tools.javac.Main

也就是说javac 这个命令和 java --module jdk.compiler/com.sun.tools.javac.Main 这个命令是一致的

java前端

列出所有的module

我的jdk现在是jdk17 , 可以看到其中有一个jdk.compiler 的module , 这个就是java编译器前端

使用module 方式调用

先创建一个hello world

vim com/Hello.java

内容如下:

package com;
public class Hello{
public static void main(String [] argc){

System.out.print(argc.length);

}
}

然后使用以下命令编译:

java  --module   jdk.compiler/com.sun.tools.javac.Main  com/Hello.java

获取class 文件:

$tree com
com
├── Hello.class
└── Hello.java

执行这个hello world 的demo:

$ java com.Hello
0

正常执行

相关阅读

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

相关阅读

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

相关阅读