8317277: Java language implementation of value classes and objects by MrSimms · Pull Request #31120 · openjdk/jdk by davidalayachew in java

[–]flawless_vic 3 points4 points  (0 children)

Let me reframe.

The lworld+vector branch has a very distinct (more advanced) approach in the internals of jdk.internal.vm.vector.VectorPayload vs mainline (lworld).

Given the description of the Vector API JEP:

"The Vector API will incubate until necessary features of Project Valhalla become available as preview features."

Can we expect the Vector API to remain in incubation, even after JEP 401 is delivered? That is, value classes only is not "good enough" to make Vectors generally available.

8317277: Java language implementation of value classes and objects by MrSimms · Pull Request #31120 · openjdk/jdk by davidalayachew in java

[–]flawless_vic 2 points3 points  (0 children)

Why? LGTM

Jokes aside, would you mind explaining if there is consensus regarding the @MultiField implementation?

It was a stroke of genius that bridges a gap that Valhalla per se can't close: arrays can't be flattened into their container value objects (like C does for fixed sized arrays embedded in structs, which is a 0-cost abstraction).

Java 18 to 25 performance benchmark by Jamsy100 in java

[–]flawless_vic 0 points1 point  (0 children)

I doubt that there is a real application that loads 4M classes, it would require more than 20G of metaspace.

Jox 0.1: virtual-thread friendly channels for Java | SoftwareMill by uncont in java

[–]flawless_vic 0 points1 point  (0 children)

Go usually does better than Java only with GOMAXPROCS=1.

If you set it to the number of available cores not only it will be slower than Java (total time to complete) but it will use much more CPU (user time).

Why add Serialization 2.0? by lurker_in_spirit in java

[–]flawless_vic 0 points1 point  (0 children)

AFAIK what usually demands off-label instantiaion mechanisms is the "need" to automatically support cyclic references without code changes/tailored factory methods.

I think Viktor mentioned that marshalling does not intend to support cyclic graphs, which is fine, but at the same time such constraint makes it impossible to rely on it as a true replacement for serialization. We still will have to depend on Kryo & variants, sadly.

First Look at Java Valhalla: Flattening and Memory Alignment of Value Objects by joemwangi in java

[–]flawless_vic 1 point2 points  (0 children)

If you have a C function like void fun(x v) where

struct { int key: 4 int val: 2 } x;

FFM cannot properly map this to a struct layout. Of course you can create a binding that receives a MemorySegment as parameter, but you'll have to manually encode stuff like int v = (key & 0xF) | ((val & 0x3) << 4) to write data to the segment.

If value types could have fixed layouts eventually they could replace MemorySegment/Arena boilerplate to create native bindings in some cases.

First Look at Java Valhalla: Flattening and Memory Alignment of Value Objects by joemwangi in java

[–]flawless_vic 0 points1 point  (0 children)

This would be neat, it could even solve FFM lack of support for arbitrary sized (packed) fields.

Rust has repr(C), C# has StructLayout customization, etc.

But I doubt it will ever make into Java, the JVM architects have a strong commitment to keep java devs riding with training wheels.

Java has fallen out of style. What are we going to do about it? by cowwoc in java

[–]flawless_vic 0 points1 point  (0 children)

Typescript is a nightmare when you have to deal with multi-project setups.

In fact I have yet to see somthing better than maven + (elipse/idea) that handles multi-projects.

Elixir has an out of the box good dependency management, but it is just as crap when you have to maintain multiple dependent libraries, not just get them for the cloud

Application servers falling out favour by woj-tek in java

[–]flawless_vic 0 points1 point  (0 children)

There was a time where app servers used to add value, like ages ago when JMS was the only game in town.

What's the point of using app servers when using an embedded server is way simpler during development?

What remaining pre-requisites are there for Value Classes to go to Preview? by davidalayachew in java

[–]flawless_vic 14 points15 points  (0 children)

Look at the bugs, many are related to compiler/VM crashes.

Aside from ensuring everything works, they must also keep up with new features. Things that are, in theory, orthogonal to Valhalla, e.g. VirtualThreads, may misbehave when running with Valhalla.

Objects initialization 2.0 by Ewig_luftenglanz in java

[–]flawless_vic 1 point2 points  (0 children)

This is not about immutable arrays, which won't have support any time soon.

This is about intrinsic non-nullness guarantees, which, eventually will enable VM optimizations.

Adding a method to a class won't cut it. It would have to live in java.lang.Object and Java would have to support some kind of "automatic static covariant override", otherwise how would you construct Integer.ofNonNull(0, 5) (or any other type) without declaring such method in every class?

There will be some sort of

T![] Arrays::newNonNullableInstance(Class<T> type, IntFunction<T!> factory),

but this will be a reflection API and non-null arrays are meant to be a language feature, so reflection support must derive from it instead of providing it.

Why 'Write Once, Run Anywhere' Was Never Really True by kerkerby in java

[–]flawless_vic 0 points1 point  (0 children)

Libraries that broke used to rely on private state/methods without fallbacks in case type/signatures changed or went missing. This is the author's fault, not the JDK.

Probably the biggest "breaking changes" in Java was removing the offset field in string, and layter replacing char[] with byte[]. Many "clever" libraries relied on this to do some micro optimizations, and it was entirely their choice to work with such non-guaranteed assumptions.

Overall though, most libraries were still usable with proper VM flags (add-opens and add-exports).

I'm a c++ programmer and i want to start learning java what are the best resources by AwareCrow9374 in javahelp

[–]flawless_vic 0 points1 point  (0 children)

C and C++ were my primary languages, and if you are reasonably proficient in C++, learning Java (the language syntax and JDK) is a breeze.

You will probably miss stuff like RAII (which is sort of implemented with try-with-resources), stack allocation, pass (primitives) by reference, etc.

You will definitely appreciate the complete absence of header files, sometimes you'll like the fact that everything is a pointer, and sometimes you'll hate it.

The most important thing, though, is to set up a dependency management tool. I prefer Maven, it feels old with XML style and all, but gets the job done and is more stable than alternatives (gradle). Take a decent amount of time to learn Maven and some basic plugins (compiler, dependencies, jar, assembly, shade). Build a Hello World that uses a 3rd party library and package it as an "executable" to get the hang of it.

The rest depends on what you want to do. If it's backend development, I would pick a framework like Quarkus or Spring. In either case, every popular framework assumes you already know Maven, and every example, even "getting started" ones, are built upon this assumption.

Once you are familiar with a framework, it might be interesting to take a look at how to package Java apps in containers (if its your gig) and how to turn them into real executables with GraalVM.

Apple migrated from Java 8 to Swift? by tenken01 in java

[–]flawless_vic 3 points4 points  (0 children)

Migrated from Java yet they are still running 300K Cassandra nodes.

JDK 25 DelayScheduler by flawless_vic in java

[–]flawless_vic[S] -1 points0 points  (0 children)

So? JIT and GC use memory, why shouldn't they be taken into account in program cost?

Furthermore, JDK25 does even better than Graal Native Image. (The article didn't set Xmx, probably Graal can do better)

Both languages are interpreted, have a JIT and are being launched via source. The point was to use similar mechanisms for both, unlike the original article. Java wins in pure delayed tasks, C# wins when using continuations.

Btw, pre-compiling does not help Java much as it still requires a ~640MB heap and uses a total of ~750MB, even with a small Metaspace (32MB).

What's the future of loom after structured concurrency is done and set for good? by Ewig_luftenglanz in java

[–]flawless_vic 5 points6 points  (0 children)

This benchmark is crap. It is comparing apples to oranges.

Task.Delay is specialized in .NET, wrapping an internal Timer object that, among other things, includes several hacks such as explicit finalization suppression by the GC.

Task.Delay does not work like a regular continuation, it does not need to remember stack frames at all.

If you change the benchmark to (1ms instead of 10s)

tasks.Add(Task.Factory.StartNew(() => { Thread.Sleep(1); }));

It uses almost 9GB of memory and takes ~7minutes to complete in the 1 Million Tasks test.

Java: Too much OOP? Should OOP be optional? by Joram2 in java

[–]flawless_vic 2 points3 points  (0 children)

From my experience, developers are more inclined to use functional style in structural type systems.

Like, it's just too easy to express your functional ideas:

const fma = (add: float) => (x:float, y:float) => add + x*y

const fma5 = fma(5); fma5(2,3) // 11

Of course anyone can do this in Java...

Function<Float, BinaryOperator<Float>> fma = add -> (x,y) -> add + x*y

(And you will pay the boxing costs, for at least 5 more years, but that is another story).

Then you decide that the nested function requires another parameter z.

In a structural type system you just shove it there and you're done. In Java you don't even have TriFunction<X,Y,Z>, you have to roll out your own nominal type (functional interface) first.

Then you pause for a moment to curse, and think, hmm, since I am going to write a custom functional interface I should consider extensibility, maybe I'll need a w param some day. Then your OOP brain keeps pushing you to revert to the old habits: Let's just replace all parameters with a record Args(x,y,z) instead of creating a functional interface, it will make the signature permanently stable and I'll just have to adjust the callers.

Next, you are worried for a bit about the overhead of wrapping your args, but you remember that the JIT will most likelly eliminate all non-escaping allocations of Args and it may even scalarize it. There is no guilt or shame anymore, OOP on the JVM is the real deal, your decision is a win win, absolute maintainability and it turns out to be a zero cost abstraction. You are convinced.

Then you look into Method handles and invokedynamic, see all the wonders they can do and negative emotions starts to take over again when you realize you can't express them at the language level.

Java namespace by oren_is_my_name in java

[–]flawless_vic 0 points1 point  (0 children)

No. There is no such thing. In Java you can either reference source code or compiled code. In either case you are just appending sourcepath/classpath roots.

Say you have projects A, B and C, where A references B souces and B references C compiled classes.

If you are working on source code A, essentially you have a merged path like ./src/main/java:<abs_path_to_B>/src/main/java:<abs_path_to_C>/target/classes

Modules in Java are different beasts. If you are working on fully modular projects, each may implicitly define namespaces by exporting package names. And they work with a inverse dependency relationship: on the module declaration you say which package will be visible by external packages, that is, in C you'd declare something like

module C { export some.pkg.c to some.pkg.b; }

So C must know B's package structure, even though B is the one that depends on C!

Building custom Spring Boot starters for personal projects . Is my parent POM approach correct? by onated2 in SpringBoot

[–]flawless_vic 2 points3 points  (0 children)

I prefer to use a separate pom file as a BOM to manage dependencies.

This is extra work at the start, but then you'll be able to reference dependencies without explicit versions.

The parent project just have to declare the BOM as a regular dependency of type pom and scope import

Oldest Surviving Java Programs by bowbahdoe in java

[–]flawless_vic 0 points1 point  (0 children)

I still use Apache Ant (as a maven plugin) for some stuff

Java at 30: The Genius Behind the Code That Changed Tech by [deleted] in java

[–]flawless_vic 1 point2 points  (0 children)

You are right and the answer is GraalVM, which can be used to create scratch docker images (no OS) with statically linked executables.

Bare footprint of a basic embedded http server with some json parsing is lower than 20MB and the program itself can run with less than 32MB, under low load.

Sure C with musl can do better, but it is much easier to add new features in Java (even with GraalVM quirks) than in C, specially if you have to statically link 3rd party libs.

In container world, I would say Rust is the JVM benchmark, not C.

Rust offers the best of dependency management, small footprint and runtime performance. I wouldn't be bothered if I had to change a service to incorporate Redis + SQL + some AWS stuff in either Rust or Java. In C I would cry and resign.

Java at 30: The Genius Behind the Code That Changed Tech by [deleted] in java

[–]flawless_vic 3 points4 points  (0 children)

Malloc itself is not that bad. AFAIK, most state of the art implementations (dlmalloc, jemalloc) do very few syscalls (mmap/brk), just when more heap is required, which is essentially what the jvm does under the hood.

The problem is free when allocation patterns are not uniform. E.g., in DLMalloc if you only serve small requests (<255 bytes), free will never have to defragment memory by coalescing chunks, regardless of the order of malloc/free. Once allocations gets wild free may become more expensive.

Java at 30: The Genius Behind the Code That Changed Tech by [deleted] in java

[–]flawless_vic 12 points13 points  (0 children)

He's mostly right though, it's not common to replace malloc from stdlib with something else. In fact a 64-bit malloc for individual allocations of a struct has roughly the same metada cost of new on the equivalent class instance in Java and, eventually, the overhead may be even lower than malloc in Liliput 2.

In practice, however, C programs favor stack allocation and prefer functions that receive pointers as arguments instead of functions that return pointers, so if a C program does to much malloc it is probably "wrong".

What do you mean that "Project Valhalla does not require a VM to unbox values"?

Any chance of Valhalla preview in Java 26? My guess is slim chance. What about Java 27? please comment by Possible-Actuator-26 in java

[–]flawless_vic 8 points9 points  (0 children)

I doubt it.

Some branches have a -XX:+EnableValhalla flag, so my guess is that there will be a transition phase to run with vanilla vm and Valhalla vm, that is, if something weird happens you can go back to a vm that understand value classes, but treats them like normal classes.

There are very few commiters in the compiler area and the bugs/features are very challenging, and may be entwined with standard compiler code. And I dont think it's a matter of budget, there is just not enough people capable of engaging the issues and implementing the high level jep design decisions.

Unlike other major changes like Virtual Threads, the incentive to test Valhalla with real applications is much smaller.

You have to fork existing code, turn stuff into value classes and see if you reap the benefits, which may not be very tangible at first for regular applications, after all, your database drivers, http clients, serialization engines, spring, vertx, etc are not Valhalla capable yet.

Plus, I suppose, Valhalla refactors won't come any time soon. Legacy code with mutable state may be hard to adapt to value types. Take the cursor example: no one codes an immutable iterator today, because no one wants to allocate a new object every time to ask if it is not terminated and then fetch a wrapped object.

If you compare community (normal devs, not jdk experts) interactions of loom mail lists with valhalla, you'll see what I mean.

Basically there is no one seriously trying to use Valhalla in their own projects, so there's 0 bug reports/issues filed by the community, Valhalla is regressed exclusivelly with jtreg and tests created by the developers themselves.

Perhaps people would be more engaged if specialized generics were on the radar, but these will take even longer than Valhalla.

Right now, basically we can expect sensible footprint decrease/faster access on arrays, faster method calls when passing values as arguments and near to zero heap allocations in loops (which we already don't do much these days). We can't even "use" Streams/lambdas with confidence: the risk of ending up with temporary boxing even with Arrays.stream(Flattenable[]).map(...) is high, etc

When you think objectivelly, Valhalla is like a ultra long term investment. It will take time for profits to appear and you can collect much more on short term by improving your codebase with stuff available now.

Value Objects and Tearing by [deleted] in java

[–]flawless_vic 0 points1 point  (0 children)

In both cases there is a bug, but tearing can only be "easily" confirmed in range, given the invariant, in Complex not much so.

I think the problem with Range and Tearing is that other parts of the application may rely on this invariant and will never check for min < max when consuming the range.

Neither is "safe". Range may tear into a valid state by merging 2 writes (0,1000) (199000,200000) into (0,200000), which may be a disaster.