I recently made this tutorial and got the code in order. Then, today, I reopened the project in eclipse and selected Run As ... Run on Server. It looks like the application performed its usual download process from the logs running in the eclipse console, but then the following error message appeared on the eclipse console the moment I expected the application to load in the browser:
Exception in thread "http-bio-8080-exec-3" java.lang.OutOfMemoryError: PermGen space
I also ran the code from this guide and opened some blob files, but I donβt think I caused this problem because this error persists even when I close everything and restart the computer before starting as ... Run the code below on the server .
I searched for an error and read messages about memory leaks from things like loading a massive file completely into memory instead of using an input stream, etc. But when I analyzed all the code in the application, I could not find large variables. I am posting the code below. Please let me know if there is anything else I should add to help you find the problem.
Can someone show me where the memory leak occurs?
Here is the link controller:
@Controller public class LinkController { @RequestMapping(value="/") public ModelAndView mainPage() {return new ModelAndView("home");} @RequestMapping(value="/index") public ModelAndView indexPage() {return new ModelAndView("home");} }
Here is the command controller:
@Controller @RequestMapping(value="/team") public class TeamController { @Autowired private TeamService teamService; @RequestMapping(value="/add", method=RequestMethod.GET) public ModelAndView addTeamPage() { ModelAndView modelAndView = new ModelAndView("add-team-form"); modelAndView.addObject("team", new Team()); return modelAndView; } @RequestMapping(value="/add", method=RequestMethod.POST) public ModelAndView addingTeam(@ModelAttribute Team team) { ModelAndView modelAndView = new ModelAndView("home"); teamService.addTeam(team); String message = "Team was successfully added."; modelAndView.addObject("message", message); return modelAndView; } @RequestMapping(value="/list") public ModelAndView listOfTeams() { ModelAndView modelAndView = new ModelAndView("list-of-teams"); List<Team> teams = teamService.getTeams(); modelAndView.addObject("teams", teams); return modelAndView; } @RequestMapping(value="/edit/{id}", method=RequestMethod.GET) public ModelAndView editTeamPage(@PathVariable Integer id) { ModelAndView modelAndView = new ModelAndView("edit-team-form"); Team team = teamService.getTeam(id); modelAndView.addObject("team",team); return modelAndView; } @RequestMapping(value="/edit/{id}", method=RequestMethod.POST) public ModelAndView edditingTeam(@ModelAttribute Team team, @PathVariable Integer id) { ModelAndView modelAndView = new ModelAndView("home"); teamService.updateTeam(team); String message = "Team was successfully edited."; modelAndView.addObject("message", message); return modelAndView; } @RequestMapping(value="/delete/{id}", method=RequestMethod.GET) public ModelAndView deleteTeam(@PathVariable Integer id) { ModelAndView modelAndView = new ModelAndView("home"); teamService.deleteTeam(id); String message = "Team was successfully deleted."; modelAndView.addObject("message", message); return modelAndView; } }
Here is TeamDAOImpl:
@Repository public class TeamDAOImpl implements TeamDAO { @Autowired private SessionFactory sessionFactory; private Session getCurrentSession() {return sessionFactory.getCurrentSession();} public void addTeam(Team team) {getCurrentSession().save(team);} public void updateTeam(Team team) { Team teamToUpdate = getTeam(team.getId()); teamToUpdate.setName(team.getName()); teamToUpdate.setRating(team.getRating()); getCurrentSession().update(teamToUpdate); } public Team getTeam(int id) { Team team = (Team) getCurrentSession().get(Team.class, id); return team; } public void deleteTeam(int id) { Team team = getTeam(id); if (team != null){getCurrentSession().delete(team);} } @SuppressWarnings("unchecked") public List<Team> getTeams() { return getCurrentSession().createQuery("from Team").list(); } }
Here is the initializer:
public class Initializer implements WebApplicationInitializer { public void onStartup(ServletContext servletContext)throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(WebAppConfig.class); servletContext.addListener(new ContextLoaderListener(ctx)); ctx.setServletContext(servletContext); Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); servlet.addMapping("/"); servlet.setLoadOnStartup(1); } }
Here is the WebAppConfig:
@Configuration @ComponentScan("com.sprhib") @EnableWebMvc @EnableTransactionManagement @PropertySource("classpath:application.properties") public class WebAppConfig { private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver"; private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password"; private static final String PROPERTY_NAME_DATABASE_URL = "db.url"; private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username"; private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect"; private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql"; private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan"; @Resource private Environment env; @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER)); dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL)); dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME)); dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD)); return dataSource; } @Bean public LocalSessionFactoryBean sessionFactory() { LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource()); sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN)); sessionFactoryBean.setHibernateProperties(hibProperties()); return sessionFactoryBean; } private Properties hibProperties() { Properties properties = new Properties(); properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT)); properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL)); return properties; } @Bean public HibernateTransactionManager transactionManager() { HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(sessionFactory().getObject()); return transactionManager; } @Bean public UrlBasedViewResolver setupViewResolver() { UrlBasedViewResolver resolver = new UrlBasedViewResolver(); resolver.setPrefix("/WEB-INF/pages/"); resolver.setSuffix(".jsp"); resolver.setViewClass(JstlView.class); return resolver; } }
Here is the command:
@Entity @Table(name="teams") public class Team { @Id @GeneratedValue private Integer id; private String name; private Integer rating; public Integer getId() {return id;} public void setId(Integer id) {this.id = id;} public String getName() {return name;} public void setName(String name) {this.name = name;} public Integer getRating() {return rating;} public void setRating(Integer rating) {this.rating = rating;} }
Here is TeamServiceImpl:
@Service @Transactional public class TeamServiceImpl implements TeamService { @Autowired private TeamDAO teamDAO; public void addTeam(Team team) {teamDAO.addTeam(team);} public void updateTeam(Team team) {teamDAO.updateTeam(team);} public Team getTeam(int id) {return teamDAO.getTeam(id);} public void deleteTeam(int id) {teamDAO.deleteTeam(id);} public List<Team> getTeams() {return teamDAO.getTeams();} }
EDIT:
If I have to set the JAVA_OPTS variable to allow class unloading and increase memory size, how to do it in Windows 7 working with tomcat 7?
I believe that I need to create a Windows system variable and possibly run something on the command line after. But what? Here is what I start with:
JAVA_OPTS="-XX:MaxPermSize=128M -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled -Xms256m -Xmx512m"