Hot questions for Using GlassFish in garbage collection

Top Java Programmings / GlassFish / garbage collection

Question:

I'm working on a web project with Java EE, and it works smooth on my computer, but when I export into a war and upload it into the server I'm receiving the following error:

[2017-02-01T23:29:09.439+0100] [Payara 4.1] [INFO] [] [] [tid: _ThreadID=40 _ThreadName=admin-thread-pool(1)] [timeMillis: 1485988149439] [levelValue: 800] [[
  ================== availabilityEnabled  skipped]]

[2017-02-01T23:31:07.548+0100] [Payara 4.1] [INFO] [NCLS-REST-00003] [javax.enterprise.admin.rest] [tid: _ThreadID=5211 _ThreadName=admin-thread-pool(143)] [timeMillis: 1485988267548] [levelValue: 800] [[
  An error occurred while processing the request. Please see the server logs for details.
org.glassfish.jersey.server.ContainerException: java.lang.OutOfMemoryError: GC overhead limit exceeded
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer$ResponseWriter.rethrow(GrizzlyHttpContainer.java:324)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer$ResponseWriter.failure(GrizzlyHttpContainer.java:306)
    at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:509)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:334)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:384)
    at org.glassfish.admin.rest.adapter.RestAdapter$2.service(RestAdapter.java:316)
    at org.glassfish.admin.rest.adapter.RestAdapter.service(RestAdapter.java:179)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:466)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:169)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.portunif.PUFilter.handleRead(PUFilter.java:231)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.portunif.PUFilter.handleRead(PUFilter.java:231)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:526)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
]]

[2017-02-01T23:31:08.403+0100] [Payara 4.1] [SEVERE] [] [javax.enterprise.system.tools.deployment.common] [tid: _ThreadID=38 _ThreadName=deployment-jar-scanner] [timeMillis: 1485988268403] [levelValue: 1000] [[
  Exception while visiting org/eclipse/persistence/internal/jpa/querydef/CriteriaQueryImpl.class of size 21034
java.lang.OutOfMemoryError: GC overhead limit exceeded
]]

In my computer, it works without any problem, with a stable memory usage around 450,000Kb - the jvm allowed memory in the server is 512Mb, is there a problem in the server or could be something in my code? as I can only see references to glassfish and sun libraries.


Answer:

When you receive an OutOfMemoryError, the stacktrace is not relevant at all. The code in the stacktrace just requires allocation of additional memory, but the memory can be consumed by objects created somewhere else.

Investigate which objects consume the memory, for example using a profiler, VisualGC or analyze the heap dump. In particular, seek for classes defined in your application, which have an unusually high number of instances in memory.

Also, think what might be different between the 2 environments. Is it possible that the application reads data from DB during deployment, and the data in DBs differ?

The usage of 450MB on your local computer is quite close to the limit of 512MB - it is possible that the server consumes more memory than your local server, because of the different server configuration. Compare how much memory is consumed by the server and your local server before you try deploying the application.

Question:

I added 100 000 rows to a the table in database (localhost) and since then I get this error:

java.lang.OutOfMemoryError: GC overhead limit exceeded

I resolved the problem by typing in consol:

javaw -XX:-UseConcMarkSweepGC

And the consol the output is (see code below for context) :

2015-08-02T02:57:22.779+0200|Info: 5
2015-08-02T02:57:22.779+0200|Info: end, time taken: 82755

It takes 82 seconds to extract one row in the database(see code at the end). It was working fine when I had less rows so I'm wondering:

  • Why would it take so much time to extract 1 row ? JPA can't possibly extract every row in an object ? Or does it ? Just wow.
  • Is there a way around this ? I mean extracting a single row in 80 seconds is borderline slow.
  • Do I really have to type the command -XX:-UseConcMarkSweepGC? What does it do ? From the doc :

Use concurrent mark-sweep collection for the old generation. (Introduced in 1.4.1)

Here is how my code is:

@EJB
private ThreadLookUpInterface ts;

@Schedule(hour = "*", minute = "*/1", second = "0", persistent = false)
@Override
public void makeTopThreadList() {
    System.out.println("" + ts.getThread(5).getIdthread());
}

my service ejb like this:

@Stateless
public class ThreadLookUpService implements ThreadLookUpInterface {

    @PersistenceContext(unitName = "my-pu")
    private EntityManager em;

    private static final String FIND_THREAD_BY_ID = "SELECT t FROM Thethread t WHERE t.idthread=:id";

    @Override
    public Thethread getThread(int threadId) {
        Query query = em.createQuery(FIND_THREAD_BY_ID);
        query.setParameter("id", threadId);
        try {
            Thethread thread = (Thethread) query.getSingleResult();
            return thread;
        } catch (NoResultException e) {
            return null;
        } catch (Exception e) {
            throw new DAOException(e);
        }
    }
}

And my entity:

@Entity
@Table(name = "thethreads")
@NamedQuery(name = "Thethread.findAll", query = "SELECT t FROM Thethread t")
public class Thethread implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private int idthread;

    private String content;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "date_posted")
    private Date datePosted;

    private int downvotes;

    @Column(name = "hot_score")
    private int hotScore;

    @Column(name = "is_pol")
    private String isPol;

    private String title;

    private String type;

    private int upvotes;

    // bi-directional many-to-one association to Category
    @OneToMany(mappedBy = "thethread", fetch = FetchType.EAGER)
    private List<Category> categories;

    // bi-directional many-to-one association to Post
    @OneToMany(mappedBy = "thethread", fetch = FetchType.EAGER)
    private List<Post> posts;

    // bi-directional many-to-one association to Category
    @ManyToOne
    @JoinColumn(name = "categories_idcategory")
    private Category category;

    // bi-directional many-to-one association to Post
    @ManyToOne
    @JoinColumn(name = "last_post")
    private Post post;

    // bi-directional many-to-one association to User
    @ManyToOne
    @JoinColumn(name = "posted_by")
    private User user;

    // bi-directional many-to-one association to ThreadVote
    @OneToMany(mappedBy = "thethread", fetch = FetchType.EAGER)
    private List<ThreadVote> threadVotes;

    public Thethread() {
    }
}

Answer:

command -XX:-UseConcMarkSweepGC? What does it do?

It sets the Garbage Collector: ConcurrentMarkSweep (CMS). The Java Heap (where objects reside during their life cycle) is partioned mainly in two: Young and Old generation. Garbage collector is in charged of clean the heap applying some algorithms or strategies on this partitions. Instead of stopping the application threads during a full garbage collect like default GC does, CMS uses one or more background threads to periodically scan through the Old generation and discard unused objects. This help you to reduce your overhead situations but the problem doesn't disappear.

extract every row in an object ? Or does it ? Just wow.Is there a way around this ? I mean extracting a single row in 80 seconds is borderline slow.

The answers first at all depends on your entity model. For example and a common problem is abuse of Eager fetch type, which cause fetch/retrieve a lot of unnecessary object executing several query statements for that. Also depends on how resolves the task your JPA implementation and the database but I suggest you start reviewing the entity model. Maybe if you post Thethread entity someone could recognize possible issues.