Issue
I have a Spring Service
, which calls an API. This Service
creates several objects and returns these to the client (of a REST request).
Is this good practice? I observe rising memory consumption with every request. Is there is no garbage collection happening?
@org.springframework.stereotype.Service("FanService")
public class Service {
private static final Logger log = LoggerFactory.getLogger(Service.class);
public List<String> allCLubsInLeague() {
try {
URI urlString = new URI("https://www.thesportsdb.com/api/v1/json/1/search_all_teams.php?l=German%20Bundesliga");
RestTemplate restTemplate = new RestTemplate();
TeamsList response = restTemplate.getForObject(urlString, TeamsList.class);
List<BundesligaTeams> bundesligaTeams = response.getTeams();
//ResponseEntity<List<BundesligaTeams>> test = t.getForEntity(urlString, BundesligaTeams.class);
List<String> teamList = new ArrayList<>();
bundesligaTeams.forEach(value -> teamList.add(value.getStrTeam()));
log.info(bundesligaTeams.get(0).getStrAlternate());
bundesligaTeams = null;
response = null;
urlString = null;
restTemplate = null;
return teamList;
} catch (Exception e) {
log.info(e.getMessage());
}
return null;
}
}
Solution
If you are not coding low-latency application with zero-garbage allocation you should focus on writing readable and maintainable code first. Only then tune performance if it's not acceptable.
It's ok to create objects if you have available memory, memory allocation is cheap comparing to a GET request. See Latency Numbers Every Programmer Should Know.
There is no reason to
null
a local variable unless you are trying to remove security credentials. Don't writebundesligaTeams = null;
and other statements at the end, these object will be collected once they are not reachable.RestTemplate
should be a separate bean. Creating this object could be expensive if the underling HTTP client creation is expensive. Consider auto-wiring the defaultRestTemplate
provided by Spring Boot.Cache the result of the GET request locally if the data is not changing often. A list of all the clubs in the German Bundesliga will change only once a year.
You should avoid creating
String
forlog.info()
call if theinfo
logging level is not enabled. Either use placeholder syntax or calllog.isInfoEnabled()
before. Check out the What is the fastest way of (not) logging? FAQ.
Answered By - Karol Dowbecki
Answer Checked By - Terry (JavaFixing Volunteer)