Flame graph üretir, grafiği nasıl yorumlayacağımızı anlatan bir yazı burada. Kullanım şöyle
asprof -d 30 -f flamegraph.html <PID>
asprof -d 30 -f flamegraph.html <PID>
Improve the scalability of Java code that uses synchronized methods and statements by arranging for virtual threads that block in such constructs to release their underlying platform threads for use by other virtual threads. This will eliminate nearly all cases of virtual threads being pinned to platform threads, which severely restricts the number of virtual threads available to handle an application's workload.
javadoc --enable-preview --source 22 -d docs Calculator.java
JMeter has two modes: CLI and Non-CLI. .... CLI mode doesn't have any user interface. But Non-CLI mode has a user interface where you can point-and-click and interact with the JMeter.Non-CLI mode should be used for recording, scripting, and smoke testing. This mode utilizes more resources (CPU and memory). CLI mode must be used for load testing, stress testing, and other forms of performance testing as well as for CI/CD pipelines. This mode doesn't eat up more resources as there is no user interface to load and render.
jmeter -n -t test_plan.jmx -l test_results.jtl
public class PremiumRecord extends InsuranceRecord {…}
public record InsuranceRecord(String type, float premium) {
private String policyNumber; // This won't compile
}public record InsuranceRecord(String type, float premium) {
private InsuranceRecord(String type, float premium) {
this.type = type;
this.premium = premium;
}
public static InsuranceRecord newInstance(String type, float premium) {
return new InsuranceRecord(type, premium);
}
}
public record InsuranceRecord(String type, float premium) {
public void setType(String type) {
this.type = type; // Won't compile
}
}
This annotation exists purely to engage better compile-time type checking. It is analogous in this way to the @Override annotation, which exists purely to capture design intent, so that humans and tools have more information to work with.
Pinning describes the condition where a virtual thread, which maps the platform thread, is stuck to the carrier thread. It means that the virtual thread can’t be unmounted from the carrier threads because the state of it can’t be stored in the heap memory. The pinned thread prevents others from utilizing the same platform thread.
Only one thread can enter it at a time. The other threads attempting to enter will be blocked until the current (running) thread exits. They would need an uninterrupted access to shared resources to prevent race conditions as well as an accurate state of the data.
var e = Executors.newVirtualThreadPerTaskExecutor();
for (int i = 0; i < 1000; i++) {
e.submit(() -> { new Test().test(); });
}
e.shutdown();
e.awaitTermination(1, TimeUnit.DAYS);
class Test {
synchronized void test() {
sleep(4000);
}
}var e = Executors.newVirtualThreadPerTaskExecutor();
for (int i = 0; i < 1000; i++) {
e.submit(() -> { new Test().test(); });
}
e.shutdown();
e.awaitTermination(1, TimeUnit.DAYS);
class Test {
private ReentrantLock lock = new ReentrantLock();
void test() {
lock.tryLock();
try {
sleep(4000);
} finally {
lock.unlock();
}
}
}Synchronized blocks in the Connector/J code were replaced with ReentrantLocks. This allows carrier threads to unmount virtual threads when they are waiting on IO operations, making Connector/J virtual-thread friendly. Thanks to Bart De Neuter for contributing to this patch. ”
This method lets you use code from other languages into your JAVA project, like C or C++. Native methods are invoked within the JAVA virtual machine but executed outside its control.
However, not all Java constructs have been retrofitted that way. Such operations include synchronized methods and code blocks. Using them causes the virtual thread to become pinned to the carrier thread. When a thread is pinned, blocking operations will block the underlying carrier thread-precisely as it would happen in pre-Loom times.
Use the following JVM parameters as options to trace the pinned thread-Djdk.tracePinnedThreads=full Prints a complete stack trace when a thread jams while pinned, highlighting native frames and frames holding monitors.-Djdk.tracePinnedThreads=short Limits the output to just the problematic frames.
./mvnw -Dskip-modulepath-tests -Dcheckstyle.skip clean org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-static-analysis:RELEASE -Drewrite.activeRecipes=org.openrewrite.staticanalysis.AddSerialAnnotationToserialVersionUID -Drewrite.exportDatatables=true
./mvnw -Dskip-modulepath-tests -Dcheckstyle.skip clean org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-static-analysis:RELEASE -Drewrite.activeRecipes=org.openrewrite.staticanalysis.MissingOverrideAnnotation -Drewrite.exportDatatables=true -Drewrite.options=ignoreAnonymousClassMethods=true
<plugin><groupId>org.openrewrite.maven</groupId><artifactId>rewrite-maven-plugin</artifactId><version>5.23.1</version><configuration><activeRecipes><recipe>org.openrewrite.staticanalysis.CommonStaticAnalysis</recipe></activeRecipes></configuration><dependencies><dependency><groupId>org.openrewrite.recipe</groupId><artifactId>rewrite-static-analysis</artifactId><version>1.3.1</version></dependency></dependencies></plugin>
--- type: specs.openrewrite.org/v1beta/recipe name: orcun.CommonStaticAnalysis displayName: Common static analysis issues description: Resolve common static analysis issues discovered through 3rd party tools. recipeList: - org.openrewrite.staticanalysis.UseDiamondOperator
<plugin><groupId>org.openrewrite.maven</groupId><artifactId>rewrite-maven-plugin</artifactId><version>5.23.1</version><configuration><activeRecipes><recipe>orcun.CommonStaticAnalysis</recipe></activeRecipes></configuration><dependencies><dependency><groupId>org.openrewrite.recipe</groupId><artifactId>rewrite-static-analysis</artifactId><version>1.3.1</version></dependency></dependencies></plugin>
./mvnw -Dskip-modulepath-tests -Dcheckstyle.skip clean org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-migrate-java:RELEASE -Drewrite.activeRecipes=org.openrewrite.staticanalysis.CompareEnumsWithEqualityOperator -Drewrite.exportDatatables=true
./mvnw -T1 -Dskip-modulepath-tests -Dcheckstyle.skip clean org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-migrate-java:RELEASE -Drewrite.activeRecipes=org.openrewrite.java.migrate.lang.StringRulesRecipes$RedundantCallRecipe -Drewrite.exportDatatables=true
Project Panama represents a significant advancement in the Java ecosystem, primarily focusing on enhancing Java’s interaction with foreign APIs, particularly those written in languages like C and C++. Traditionally, Java used the Java Native Interface (JNI) to invoke foreign functions, but JNI had several limitations. Project Panama addresses these by removing the need to write native code wrappers in Java, replacing the ByteBuffer API with a more advanced Memory API, and introducing a secure, memory-efficient method to invoke native code from Java. The project comprises several key components, including the Foreign-Function and Memory API, the Vector API, and the JExtract tool.
Accessing the value of an Integer (non-primitive) includes an extra memory access
... give the user the ability to flatten his objects and enjoy the performance of primitives in exchange for some limitations ...
// Beforepublic class Point {private final int x;private final int y;}// Afterpublic primitive class Point {private final int x;private final int y;}
<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.9</version></dependency>
import com.google.gson.annotations.Since;import com.google.gson.annotations.Until;public class Product {@Since(1.0)private String name;@Until(2.0)private double price;// getters and setters}
import com.zaxxer.hikari.HikariDataSource;
HikariConfig config = ... HikariDataSource ds = new HikariDataSource(config);
public class HikariDataSource extends HikariConfig implements DataSource, Closeable {
...
private final AtomicBoolean isShutdown = new AtomicBoolean();
...
}public boolean isClosed() {
return isShutdown.get();
}public record FilmWithRecord(String title, String director, int releaseYear) {public static class Builder {private String title;private String director;private int releaseYear;public Builder title(String title) {this.title = title;return this;}public Builder director(String director) {this.director = director;return this;}public Builder releaseYear(int releaseYear) {this.releaseYear = releaseYear;return this;}public FilmWithRecord build() {return new FilmWithRecord(title, director, releaseYear);}}}
// Example of using the builder:FilmWithRecord film = new FilmWithRecord.Builder().title("The Dark Knight").director("Christopher Nolan").releaseYear(2008).build();
<?xml version="1.0" encoding="UTF-8"?><configuration status="WARN"><property name="logging.error.file.name" value="error-log" /><property name="logging.error.file.path" value="./"/><property name="logging.file.name" value="info-log" /><property name="logging.file.path" value="./"/><!-- Normal log appender --><appender name="INFO_FILE" class="ch.qos.logback.core.FileAppender"><file>${logging.file.path}/${logging.file.name}</file><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO, DEBUG, TRACE</level></filter><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR, WARN</level><onMatch>DENY</onMatch><onMisMatch>NEUTRAL</onMisMatch></filter></appender><!-- Error log appender --><appender name="ERROR_FILE" class="ch.qos.logback.core.FileAppender"><file>${logging.error.file.path}/${logging.error.file.name}</file><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>ERROR, WARN</level></filter><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO, DEBUG, WARN</level><onMatch>DENY</onMatch><onMisMatch>NEUTRAL</onMisMatch></filter></appender><root level="INFO"><appender-ref ref="INFO_FILE"/><appender-ref ref="ERROR_FILE"/></root></configuration>
- Trace < Debug < Info < Warn < Error < Fatal- LevelFilter filters events based on exact level matching. If the event's level is equal to the configured level, the filter accepts or denies the event, depending on the configuration of the onMatch and onMismatch properties.- The ThresholdFilter filters events below the specified threshold.
@ClassRule public static LocalStackContainer container = new LocalStackContainer(DockerImageName.parse("localstack/localstack:3.0.2")) .withServices(LocalStackContainer.Service.SQS) .withEnv("SQS_ENDPOINT_STRATEGY", "path"); // Burası @BeforeClass public static void beforeClass() { container.execInContainer("awslocal", "sqs", "create-queue", "--queue-name", "myqueue"); }
void insertData() throws URISyntaxException { System.setProperty("aws.accessKeyId", container.getAccessKey()); System.setProperty("aws.secretKey", container.getSecretKey()); SqsClient sqs = SqsClient.builder() .endpointOverride(container.getEndpointOverride(LocalStackContainer.Service.SQS)) .credentialsProvider( StaticCredentialsProvider.create( AwsBasicCredentials.create(container.getAccessKey(), container.getSecretKey()) ) ) .region(Region.of(container.getRegion())) .build(); ... }
String xadd(K key, Map<K, V> body);
<dependency><groupId>com.redis</groupId> <artifactId>testcontainers-redis</artifactId> <version>2.0.1</version> <scope>test</scope> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>6.2.3.RELEASE</version> </dependency>
import com.redis.testcontainers.RedisContainer; @ClassRule public static final RedisContainer container = new RedisContainer(DockerImageName.parse("redis:6.2.6")) .withLogConsumer(new Slf4jLogConsumer(LOGGER).withPrefix("Docker"));
import io.lettuce.core.RedisClient; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; void insertData() { String redisURI = container.getRedisURI(); try (RedisClient client = RedisClient.create(redisURI); StatefulRedisConnection<String, String> connection = client.connect()) { RedisCommands<String, String> syncCommands = connection.sync(); for (int index = 0; index < ITEM_COUNT; index++) { // Redis Streams messages are string key/values in Java. Map<String, String> messageBody = createMessageBody(index); String messageId = syncCommands.xadd( STREAM_NAME, messageBody); LOGGER.info("Message {} : {} posted", messageId, messageBody); } } } Map<String, String> createMessageBody(int index) { Map<String, String> messageBody = new HashMap<>(); messageBody.put("speed", String.valueOf(index)); messageBody.put("direction", "270"); messageBody.put("sensor_ts", String.valueOf(System.currentTimeMillis())); return messageBody; }
The DriverManager class included with the java.sql package tracks the loaded JDBC drivers. The client application retrieves the desired database connections through the DriverManager class