java – Como trabalhar com Classes que tenham outras Classes como atributo SpringBoot

Eae gente , essa é primeira vez que to programando pra web e to usando o spring boot pra isso , é um projeto da faculdade onde o FrontEnd vai ser feito em JS com React e o Back feito em JAVA com Spring . com o banco de dados postgres.
Eu fiquei com o Back end , e tudo ia bem até eu precisar trabalhar com classes compostas (classes que tem outras classes como atributo).
Tenho que fazer meio que uma lista de compra , uma Classe carrinho que tem como atributo um arrayList de compras , no qual compra tem como atributo um produto.

package com.api.springboot.model;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.hibernate.annotations.Cascade;
import org.springframework.data.annotation.CreatedDate;

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "carrinhos")
public class Carrinho implements Serializable {

    private static final long serialVersonUID = 1L;

    public Carrinho() {
        this.terminado = false;
    }


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String nome;
    private boolean terminado;
    private float precoTotal;


    @OneToMany
            //(cascade = CascadeType.ALL, mappedBy = "carrinhos")
    @JoinColumn(name = "carrinho_id")
    private List<Compra> compras = new ArrayList<>();

    @ManyToOne
    private Comprador comprador;

    @CreatedDate
    private Date criadoEm = new Date();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public boolean isTerminado() {
        return terminado;
    }

    public void setTerminado(boolean terminado) {
        this.terminado = terminado;
    }

    public float getPrecoTotal() {
        return precoTotal;
    }

    public void setPrecoTotal(float precoTotal) {
        this.precoTotal = precoTotal;
    }

    public void setCriadoEm(Date criadoEm) {
        this.criadoEm = criadoEm;
    }

    public List<Compra> getCompras() {
        return compras;
    }

    public void setCompras(List<Compra> compras) {
        this.compras = compras;
    }

    public void adicionarCompra(Compra compra){
        this.compras.add(compra);
    }

    public Date getCriadoEm() {
        return criadoEm;
    }

    public Comprador getComprador() {
        return comprador;
    }

    public void setComprador(Comprador comprador) {
        this.comprador = comprador;
    }

    public void add(Compra compra){
        compras.add(compra);
    }

    @Override
    public String toString() {
        return "Carrinho{" +
                "id=" + id +
                "n, nome='" + nome + ''' +
                "n, terminado=" + terminado +
                "n, precoTotal=" + precoTotal +
                "n, compras=" + compras +
                "n, comprador=" + comprador +
                "n, criadoEm=" + criadoEm +
                '}';
    }


}


package com.api.springboot.model;
import org.hibernate.annotations.ManyToAny;
import org.springframework.data.annotation.CreatedDate;

import javax.persistence.*;
import java.io.Serializable;
import java.time.*;
import java.util.Date;

@Entity
@Table(name = "compras")
public class Compra implements Serializable {


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "produto_id")
    private Produto produto = new Produto();

    private int quantidade;
    private float precoTotal;

    @ManyToOne
    @JoinColumn(name = "carrinho_id")
    private Carrinho carrinho;

    @OneToOne
    private Promocao promocao;

    @CreatedDate
    private Date criadoEm = new Date();

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Produto getProduto() {
        return produto;
    }

    public void setProduto(Produto produto) {
        this.produto = produto;
    }

    public int getQuantidade() {
        return quantidade;
    }

    public void setQuantidade(int quantidade) {
        this.quantidade = quantidade;
    }

    public float getPrecoTotal() {
        return precoTotal;
    }

    public void setPrecoTotal(float precoTotal) {
        this.precoTotal = precoTotal;
    }

    public Date getCriadoEm() {
        return criadoEm;
    }

    public Promocao getPromocao() {
        return promocao;
    }

    public void setPromocao(Promocao promocao) {
        this.promocao = promocao;
    }

    public void setCriadoEm(Date criadoEm) {
        this.criadoEm = criadoEm;
    }

    public Carrinho getCarrinho() {
        return carrinho;
    }

    public void setCarrinho(Carrinho carrinho) {
        this.carrinho = carrinho;
    }

    @Override
    public String toString() {
        return "Compra{" +
                "id=" + id +
                ", produto=" + produto +
                ", quantidade=" + quantidade +
                ", precoTotal=" + precoTotal +
                ", carrinho=" + carrinho +
                ", promocao=" + promocao +
                ", criadoEm=" + criadoEm +
                '}';
    }
}


´´´
´´´
package com.api.springboot.model;

import org.springframework.data.annotation.CreatedDate;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.Date;

@Entity
@Table(name = "produtos")
public class Produto {
    private static final long serialVersonUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String nome;
    private float preco;
    private float peso;
    private boolean tipo;

    @ManyToOne
    private Categoria categoria;

    @CreatedDate
    private Date criadoEm = new Date();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() { return nome; }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public float getPreco() {
        return preco;
    }

    public void setPreco(float preco) {
        this.preco = preco;
    }

    public float getPeso() {
        return peso;
    }

    public void setPeso(float peso) {
        this.peso = peso;
    }

    public boolean isTipo() {
        return tipo;
    }

    public void setTipo(boolean tipo) {
        this.tipo = tipo;
    }

    public Date getCriadoEm() {
        return criadoEm;
    }

    public Categoria getCategoria() {
        return categoria;
    }

    public void setCategoria(Categoria categoria) {
        this.categoria = categoria;
    }

    @Override
    public String toString() {
        return "Produto{" +
                "id=" + id +
                ", nome='" + nome + ''' +
                ", preco=" + preco +
                ", peso=" + peso +
                ", tipo=" + tipo +
                ", categoria=" + categoria +
                ", criadoEm=" + criadoEm +
                '}';
    }
}

Essas são as 3 classes principais vou colocar somente o controlador de carrinho pois se me ajudarem com ele acredito que consigo usar a lógica para os outros.

package com.api.springboot.controllers;

import com.api.springboot.model.Carrinho;
import com.api.springboot.model.Compra;
import com.api.springboot.repository.CarrinhoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping(value = "/api")
public class CarrinhoController {

    @Autowired
    CarrinhoRepository carrinhoRepository;

    @GetMapping("/carrinhos")
    public List<Carrinho> listarCompras(){
        return carrinhoRepository.findAll();
    }

    @GetMapping("/carrinho/{id}")
    public Carrinho carrinhoById(@PathVariable(value = "id") long  id){
        return carrinhoRepository.findById(id);
    }

    @PostMapping("/carrinho")
    public Carrinho salvarCarrinho(@RequestBody Carrinho carrinho){
        return carrinhoRepository.save(carrinho);
    }

    @DeleteMapping("/carrinho")
    public void deletaCarrinho(@RequestBody Carrinho carrinho){
        carrinhoRepository.delete(carrinho);
    }

    @DeleteMapping("/carrinho/{id}")
    public void deletetById(@PathVariable(value = "id")long id){
        carrinhoRepository.deleteById(id);
    }

    @PutMapping("/carrinho/put")
    public Carrinho atualizarCarrinho(@RequestBody Carrinho carrinho){
        return carrinhoRepository.save(carrinho);
    }


    @PostMapping("/teste/{id}")
    public void add(@PathVariable(value = "id") long id , @RequestBody Compra x){
        Carrinho instancia = carrinhoRepository.findById(id);
        System.out.println(instancia);
        System.out.println(x);
//        instancia.add();
//        carrinhoRepository.save(instancia);
//        System.out.println("Rodou o dream do dream quero");
//        System.out.println(instancia);
    }

}

A minha dúvida é , como que eu adiciono uma compra em carrinho . Eu tentei usar a compra x vindo do front como parâmetro e adicionar ela , só que ela vem nula.
inserir a descrição da imagem aqui
Aí uma foto de como chega , eu nunca usei injeção de dependências e todos os tutorias os professores só usam classes com atributos de tipo int,String,boolean …

java – How to break up a request into multiple requests

I have a question about following scenario I am trying to implement in Java JAX-RS REST:

  1. a client app sends request to my api, lets call it MY-API
  2. MY-API receives request, and sends it to vendor api (VENDOR-API)
  3. VENDOR-API replies back to MY-API
  4. MY-API replies back to the client

My questions is about point 2 and 3 above.

  • Is it possible to break up request coming from client app once it is
    received in MY-API so that MY-API sends multiple requests to
    VENDOR-API instead of one?
  • And then upon receiving the requests from VENDOR-API, combine them
    back into single response to client app?

I am thinking about something like this in pseudo code:

@Path("cars")
public class CarsController
{
     1. send request to /car-detail endpoint
     1.a. get response from /userDetails endpoint

     2. send request to /car-image endpoint
     2.a. get response from /userImages endpoint
     
     3. send request to /car-history endpoint
     3.a. get response from /userHistory endpoint

     5. Somehow build response for /cars from the
        3 requests above and send response back to client
}

java – Android Call Forwarding: How does Windows “Your Phone” app work with Android?

For a long time now, I have been unable to wrap my head around how Microsoft has been able to achieve forwarded android calls without special privileges. I know the more modern integrated Samsung features definitely have something akin to that (e.g. mirroring multiple apps on PC), but this shouldn’t be the case for base android features. Primarily, I am concerned with call forwarding. Everything else makes more sense.

A companion app is installed on the phone that is given required permissions, pairs to the PC then reads:notifications, call logs, media and folders. Notification access allows for certain notifications to get replies, in addition to obviously making them readable.

However, Android calls are very locked down for security. I’ve looked extensively for reference on how Microsoft achieved it but I could only find many pages of guides and news articles showing it off.

The closest hunch I had was that maybe the computer’s bluetooth chipset was acting like that of a headset but after trying it several months ago I came to a dead end. When the device class was all but a few the phone refused to connect, even with different devices and setups.

It would be nice to see a cross platform solution for this. I use a Mac and an Android Phone. Like many, I need the freedom of android but require a mac for development work. I hate how *Apple has its own protectionist ecosystem, however similar restrictions are appearing on the other side of the coin now too.

If someone could shed some light I’d really appreciate it. I would love to work on an open, and cross platform alternative soon. I’m aware proprietary solutions such as AirDoid exists but currently none with no call forwarding unfortunately. That is what seems the hardest part to figure out.

java – Opinions on using standardized J2EE APIs over specific over vendor APIs

I have always advocated the use of standardized api, and currently use it on my code. However i always get very strong resistance when it comes to code review, even on projects i have designed and built from scratch which there is no existing code that i will conflict with.

I use standardized API to insure that i am in complete control of the architecture.

One example is the use of JSR-330 inject, i use @inject, @named, etc… Instead of spring specific @autowire and @qualifier, this is to insure that my business code remain as immutable as possible.

They could not seem to pick up when i explain, their arguments are usually:

  • Spring is a lot more modern, or that’s 2009 according to my Google search.

  • If they get cornered, it becomes: Well just use code we already use, so we can understand it quickly.

I’m not discounting that i may be wrong, so i am interested in hearing other people’s opinions.

Why does the Java CompletableFuture API uses long + TimeUnit instead of Duration?

Java 9 introduced many new methods in the CompletableFuture API that support execution timeouts.
For example:

public CompletableFuture<T> orTimeout​(long timeout, TimeUnit unit);

public CompletableFuture<T> completeOnTimeout​(T value, long timeout, TimeUnit unit);

More can be found in the documentation:
https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CompletableFuture.html#completeOnTimeout-T-long-java.util.concurrent.TimeUnit-

These methods take a long and a TimeUnit as arguments. Is there a specific reason it has been done so? Wouldn’t Duration be a better choice here?

public CompletableFuture<T> orTimeout​(Duration duration);

public CompletableFuture<T> completeOnTimeout​(T value, Duration duration);

Como unir dos listas en otra lista JAVA

Tengo tres listas, L1 y L2 que son listas ordenadas, y L que es donde hay que unir L1 y L2 de manera ordenada de pequeño a mayor. No puedo usar el mítico metodo de new(Nodo), por lo que tengo que ir enlazando L1 y L2 a L y ir borrando de las listas L1 y L2 cuando ya esten en L. En caso de que L no este vacia hay que borrar su contenido.

Es decir, si tengo, L1 -> 1 3 6 7, L2 -> 2 4 5 9 y L -> 0 8, el resultado sera L -> 1 2 3 4 5 6 7 9.

El metodo se come lo que hay en la lista L y une en esa misma lista L1 y L2, dejando vacias L1 y L2.

Mi problema es que no consigo acertar con la implementación del metodo, os dejo lo que he implementado hasta ahora por si me podeis decir cual es el fallo o como tendría que hacer.

public class Lista {

    private Nodo first;
    private int size;

    private static class Nodo {
        private Nodo next;
        private int info;

        public Nodo(int datum) {
            this.info = datum;
        }
    }

    public boolean isEmpty() {
        return this.size == 0;
    }

    public int size() {
        return this.size;
    }

    public Lista(Scanner input) {

        this.first = null;
        this.size = 0;

        if (input.hasNext()) {
            this.first = new Nodo(input.nextInt());
            this.size++;

            Nodo current = first;
            while (input.hasNext()) {
                current.next = new Nodo(input.nextInt());
                this.size++;
                current = current.next;
            }
        }
    }

    public String toString() {
        StringBuilder sb = new StringBuilder("( ");
        Nodo current = this.first;
        while (current != null) {
            sb.append(current.info + " ");
            current = current.next;
        }
        sb.append(") (" + this.size + " elemento)");
        return sb.toString();
    }

    

public void comerUnir(Lista List1, Lista List2) {
    
        Nodo current1 = List1.first;
        Nodo current2 = List2.first;
        
        int kop1 = List1.size();
        int kop2 = List2.size();
        
        int tamaño = this.size();
        Nodo current = this.first;
            
        if(this.first == null) {
            
            if (current2.info > current1.info) {
                this.first = current1;
                current = this.first;
                current1 = current1.next;
                kop1--;
                tamaño++;
            }else {
                this.first = current2;
                current = this.first;
                current2 = current2.next;
                kop2--;
                tamaño++;
            }
        }else {
            
            while(kop2 != 0 || kop1 != 0) {
                
                if (kop1 == 0) {
                    current.next = current2;
                    current2 = current2.next;
                    current = current.next;
                    kop2--;
                    tamaño++;
                    
                }else if (kop2 == 0) {
                    current.next = current1;
                    current1 = current1.next;
                    current = current.next;
                    kop1--;
                    tamaño++;
                    
                }else {
                    if (current2.info > current1.info) {
                        current.next = current1;
                        current = current.next;
                        current1 = current1.next;
                        kop1--;
                        tamaño++;
                    }else {
                        current.next = current2;
                        current = current.next;
                        current2 = current.next;
                        kop2--;
                        tamaño++;
                    }
                }
            }
            this.size = tamaño;
        }
            
            
            
    }

public static void main(String() args) throws FileNotFoundException {
        
        Lista l1 = new Lista(new Scanner(new File("files/G1/lista3.txt")));
        Lista l2 = new Lista(new Scanner(new File("files/G1/lista4.txt")));
        Lista l = new Lista(new Scanner(new File("files/G1/lista1.txt")));

        System.out.printf("L lista: %s%n%n se come y une la lista L1: %s%n%n"
                + "y la lista L2 %s%n%n", l, l1, l2);
        l.comerUnir(l1, l2);
        System.out.printf("Resultado%n%nL = %s%n%nL1 = %s%n%nL2 = %s%n", l, l1, l2);
    }
}

java – Error checkbox no seleccionado FileUpload

Tengo un problema con unos checkbox, Cuando no son seleccionados me saca un error el programa y cuando los marco TODOS el programa funciona correctamente.
Necesito que si uno no es seleccionado se convierta en null.

        String checkbox1=items.get(4).getName();
        String checkbox2=items.get(5).getName();
        String checkbox3=items.get(6).getName();
        String checkbox4=items.get(7).getName();
        String checkbox5=items.get(8).getName();

java – Error al enviar JSON a servicio rest con spring

Estoy realizando un servicio rest con java mi problema es al enviar el json la verdad no se que paso la verdadd ayer funciono abri de nuevo ejecute y hoy no funciono mmmm, estoy usando la libreria de Java Json el error mas exacto es ERROR EN EL SERVICIO REST POST : org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type (org.json.JSONObject) lo estoy probando con POSTMAN enviando un json al method @PostMapping de la siguiente manera {"apellidos":"apellidosmios","correo":"correomio","nombres":"nombremio"} y funciona bien me devuleve el json armado con los datos que envie de una clase VO, mi codigo en el rest es el siguiente.

@RestController
@RequestMapping("appday/usuarios")
public class Usuariorest {

    // Recibe parametros en formato json para insertar usuario
    // http://localhost:8080/appday/usuarios
    @PostMapping
    public CUsuarioVO registrarUsuario(@RequestBody CUsuarioVO usvo) {
        System.out.println("llego al post");

        usvo.setNombres(usvo.getNombres());
        usvo.setApellidos(usvo.getApellidos());
        usvo.setCorreo(usvo.getCorreo());

        return usvo;
    }
}

Lo estoy consumiendo de la siguiente manera

import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

public class RestUsuario {

public static void restPostUsuario() {
        // // Envia el json con los datos al service @PostMapping
        RestTemplate rest = new RestTemplate();
        try {
            JSONObject json = new JSONObject();
            json.put("nombres", "Alejandro");
            json.put("apellidos", "Garcia");
            json.put("correo", "alejogmailcom");
            String resultado = rest.postForObject("http://localhost:8080/appday/usuarios", json, String.class);
            System.out.println("El resultado del post service rest es : " + resultado);
        } catch (JSONException | RestClientException e) {
            System.out.println("ERROR EN EL SERVICIO REST POST : " + e);
            // ERROR EN EL SERVICIO REST POST : org.springframework.web.client.RestClientException:
            //Could not write request: no suitable HttpMessageConverter found for request type 
            // (org.json.JSONObject)
        }
    }
}

java – Base Class System for splitting a spigot command in subcommands

Related to this question: Spigot Plugin: Generic form of the plugin’s main clas

I’ve created a Clan-Plugin, in which I have one “main” command, which is simply /clan. Then there are several sub-commands, e.g. /clan leave, /clan money, etc. There are also subcommands that require multiple arguments, like /clan create, where you have to provide details about the clan you want to create.

My very basic problem is, that spigot only offers the possibility to implement commands based on the first word, and not the arguments. What you have to do is manually differ between the subcommands, and then execute the code. In the past I did this by having a massive if-elseif-elseif-… construct in the executor method of the command, with the code of the sub-commands being placed in methods. However, that made this class become really massive oover the time, until it hit the 1000 lines recently. I really thought I should refactor the command, so I came up with the following idea (which I successfully implemented).

I created a base class for all subcommands, AbstractCommand, and a Child Class (which is still abstract) for sub-commands, that have to be confirmed before being executed (e.g. deletion of the clan) AbstractConfirmCommand. Also I wrote a little CommandRegistry-Class to store all the implementations of the AbstractCommand, and find the proper one to execute when necessary. Then in my Main class (which can be found in above link, if there is anyone interested), I register all the Implementations of AbstractCommand. My “Spigot-ClanCommand-Class” has now shrunk down to 80 lines, with which I’m quite happy to be honest. However, I’m not experienced at all with abstract classes, and am not even sure if an abstract class was the better choice over an interface. Here’s my code, I hope I could make it clear what it’s supposed to do.

AbstractCommand:

import org.bukkit.command.Command;
import org.bukkit.entity.Player;

public abstract class AbstractCommand {

    protected final String commandName;
    
    protected AbstractCommand(String commandName) {
        this.commandName = commandName;
    }
    
    public abstract void execute(Player player, Command cmd, String arg2, String() args);
    
    public String getCommandName() {
        return commandName;
    }
    
}

AbstractConfirmCommand:

import org.bukkit.command.Command;
import org.bukkit.entity.Player;

import com.clanplugin.manager.MessageManager;

public abstract class AbstractConfirmCommand extends AbstractCommand {

    private int requiredPositionOfConfirm = 1;
    
    protected AbstractConfirmCommand(String commandName) {
        super(commandName);
    }

    protected void setConfirmPosition(int position) {
        requiredPositionOfConfirm = position;
    }
    
    @Override
    public void execute(Player player, Command cmd, String arg2, String() args) {
        if (args.length < requiredPositionOfConfirm || args.length > requiredPositionOfConfirm + 1) {
            player.sendMessage(MessageManager.badNumberOfArguments());
            return;
        }
        
        if (args.length == requiredPositionOfConfirm) {
            withoutConfirm(player, cmd, arg2, args);
            return;
        }
        
        if (args.length == requiredPositionOfConfirm + 1) {
            if (args(requiredPositionOfConfirm).equalsIgnoreCase("confirm")) {
                withConfirm(player, cmd, arg2, args);
            } else {
                withoutConfirm(player, cmd, arg2, args);
            }
            return;
        }
    }
    
    protected abstract void withoutConfirm(Player player, Command cmd, String arg2, String() args);
    
    protected abstract void withConfirm(Player player, Command cmd, String arg2, String() args);
}

CommandRegistry:

import java.util.HashSet;

import org.bukkit.command.Command;
import org.bukkit.entity.Player;

import com.clansystem.manager.MessageManager;

public class CommandRegistry {

    private HashSet<AbstractCommand> registeredCommands;
    
    public CommandRegistry() {
        registeredCommands = new HashSet<AbstractCommand>();
    }
    
    public void registerCommand(AbstractCommand command) {
        registeredCommands.add(command);
    }
    
    public void executeCommand(Player player, Command cmd, String arg2, String() args) {
        for (AbstractCommand registeredCommand : registeredCommands) {
            if (registeredCommand.getCommandName().equalsIgnoreCase(args(0))) {
                registeredCommand.execute(player, cmd, arg2, args);
                return;
            }
        }
        player.sendMessage(MessageManager.getHelpMessage());
    }
}

ClanCommand:

public class ClanCommand implements CommandExecutor {
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String arg2, String() args) {

        if (!(sender instanceof Player)) {
            sender.sendMessage("Clan-Commands können nur von Spielern ausgeführt werden.");
            return true;
        }

        Player player = (Player) sender;

        //Some checks which are irrelevant here... (e.g. command cooldown, permission-check etc)
        
        if (args.length == 0) {
            player.sendMessage(MessageManager.getHelpMessage());
            return true;
        }

        
        Main.getCommandRegistry().executeCommand(player, cmd, arg2, args);

        return true;
    }
}

Finally, I’ll append an example of an implementation of AbstractCommand:

import org.bukkit.command.Command;
import org.bukkit.entity.Player;

import com.clanplugin.commands.AbstractCommand;
import com.clanplugin.manager.MessageManager;
import com.clanplugin.utils.PermissionUtils;

public class ShowMaxClanMemberCommand extends AbstractCommand {

    public ShowMaxClanMemberCommand() {
        super("maxmember");
    }

    @Override
    public void execute(Player player, Command cmd, String arg2, String() args) {
        int limit = PermissionUtils.getTotalClanMembersAllowed(player);

        player.sendMessage(MessageManager.getMaxMemberMessage(limit));
    }

}

What I want to know is, if the basic idea of creating an abstract class is “good practice”, and how I can improve my construct. Also I’m pretty new to the site, and I’m not sure if this is too much code for one post. If so, please tell me 🙂

java – AnonPage memory leak

Our service notices some hosts having large anon pages like these from pmap -x:

0000000580000000 9486088 9479172 9479172 rw— [ anon ]

meanwhile, our other regular hosts have much smaller anon pages like

0000000580000000 9486176 5730788 5730788 rw— [ anon ]

What possibly creates such large blocks?

I’ve tried heap dumping the process but the resulting heaps are about the same size. The difference in AnonPages account for ~3 gigs of extra memory the process uses.